Skip to content

Commit 8027e5a

Browse files
Format and write commit for io.py
1 parent cdcf62d commit 8027e5a

File tree

4 files changed

+132
-76
lines changed

4 files changed

+132
-76
lines changed

.pylintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[MASTER]
22
py-version=3.5
3-
disable=R0902,R0913
3+
disable=R0902,R0913,R0917

cyaron/io.py

Lines changed: 127 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,87 @@
1+
"""
2+
A module that provides a class IO to process the input and output files.
3+
Classes:
4+
IO: IO tool class. It will process the input and output files.
5+
"""
16
from __future__ import absolute_import
2-
from .utils import *
3-
from . import log
4-
from io import open, IOBase
5-
import subprocess
6-
import tempfile
77
import os
88
import re
9+
import subprocess
10+
import tempfile
11+
from typing import Union, overload
12+
from io import IOBase
13+
from . import log
14+
from .utils import list_like, make_unicode
915

1016

11-
class IO(object):
17+
class IO:
1218
"""Class IO: IO tool class. It will process the input and output files."""
13-
def __init__(self, input_file=None, output_file=None, data_id=None, file_prefix=None, input_suffix='.in', output_suffix='.out', disable_output=False):
14-
"""__init__(self, input_file=None, output_file=None, data_id=None, file_prefix=None, input_suffix='.in', output_suffix='.out', disable_output=False) -> None
15-
input_file, output_file overload:
16-
None -> make a temp file (if file_prefix is None)
17-
file object -> treat the file-like object as in/output file
18-
int -> open file by file descriptor
19-
str -> a filename or filename template like 'awd{}.in'. ``{}`` will be replaced by ``data_id``
20-
int data_id -> the id of the data. if it's None, the file names will not contain the id.
21-
legacy argumants:
22-
str file_prefix -> the prefix for the input and output files
23-
str input_suffix = ".in" -> the suffix of the input file
24-
str output_suffix = ".out" -> the suffix of the output file
25-
disable_output -> bool, set to True to disable output
26-
Examples:
27-
IO("a","b") -> create input file "a" and output file "b"
28-
IO("a.in","b.out") -> create input file "a.in" and output file "b.out"
29-
IO(file_prefix="data") -> create input file "data.in" and output file "data.out"
30-
IO(file_prefix="data",data_id=1) -> create input file "data1.in" and output file "data1.out"
31-
IO(file_prefix="data",input_suffix=".input") -> create input file "data.input" and output file "data.out"
32-
IO(file_prefix="data",output_suffix=".output") -> create input file "data.in" and output file "data.output"
33-
IO(file_prefix="data",data_id=2,input_suffix=".input") -> create input file "data2.input" and output file "data2.out"
34-
IO("data{}.in","data{}.out",data_id=2) -> create input file "data2.in" and output file "data2.out"
35-
IO(open('data.in', 'w+'), open('data.out', 'w+')) -> input file "data.in" and output file "data.out"
19+
20+
@overload
21+
def __init__(self,
22+
input_file: Union[IOBase, str, int, None] = None,
23+
output_file: Union[IOBase, str, int, None] = None,
24+
data_id: Union[str, None] = None,
25+
disable_output: bool = False):
26+
...
27+
28+
@overload
29+
def __init__(self,
30+
data_id: Union[str, None] = None,
31+
file_prefix: Union[str, None] = None,
32+
input_suffix: Union[str, None] = '.in',
33+
output_suffix: Union[str, None] = '.out',
34+
disable_output: bool = False):
35+
...
36+
37+
def __init__(self,
38+
input_file: Union[IOBase, str, int, None] = None,
39+
output_file: Union[IOBase, str, int, None] = None,
40+
data_id: Union[str, None] = None,
41+
file_prefix: Union[str, None] = None,
42+
input_suffix: Union[str, None] = '.in',
43+
output_suffix: Union[str, None] = '.out',
44+
disable_output: bool = False):
45+
"""
46+
Args:
47+
input_file (optional): input file object or filename or file descriptor.
48+
If it's None, make a temp file. Defaults to None.
49+
output_file (optional): input file object or filename or file descriptor.
50+
If it's None, make a temp file. Defaults to None.
51+
data_id (optional): the id of the data. It will be add after
52+
`input_file` and `output_file` when they are str.
53+
If it's None, the file names will not contain the id. Defaults to None.
54+
file_prefix (optional): the prefix for the input and output files. Defaults to None.
55+
input_suffix (optional): the suffix of the input file. Defaults to '.in'.
56+
output_suffix (optional): the suffix of the output file. Defaults to '.out'.
57+
disable_output (optional): set to True to disable output file. Defaults to False.
58+
Examples:
59+
>>> IO("a","b")
60+
# create input file "a" and output file "b"
61+
>>> IO("a.in","b.out")
62+
# create input file "a.in" and output file "b.out"
63+
>>> IO(file_prefix="data")
64+
# create input file "data.in" and output file "data.out"
65+
>>> IO(file_prefix="data",data_id=1)
66+
# create input file "data1.in" and output file "data1.out"
67+
>>> IO(file_prefix="data",input_suffix=".input")
68+
# create input file "data.input" and output file "data.out"
69+
>>> IO(file_prefix="data",output_suffix=".output")
70+
# create input file "data.in" and output file "data.output"
71+
>>> IO(file_prefix="data",data_id=2,input_suffix=".input")
72+
# create input file "data2.input" and output file "data2.out"
73+
>>> IO("data{}.in","data{}.out",data_id=2)
74+
# create input file "data2.in" and output file "data2.out"
75+
>>> IO(open('data.in', 'w+'), open('data.out', 'w+'))
76+
# input file "data.in" and output file "data.out"
3677
"""
3778
if file_prefix is not None:
3879
# legacy mode
39-
input_file = '{}{{}}{}'.format(self.__escape_format(file_prefix), self.__escape_format(input_suffix))
40-
output_file = '{}{{}}{}'.format(self.__escape_format(file_prefix), self.__escape_format(output_suffix))
80+
input_file = '{}{{}}{}'.format(self.__escape_format(file_prefix),
81+
self.__escape_format(input_suffix))
82+
output_file = '{}{{}}{}'.format(
83+
self.__escape_format(file_prefix),
84+
self.__escape_format(output_suffix))
4185
self.input_filename, self.output_filename = None, None
4286
self.__input_temp, self.__output_temp = False, False
4387
self.__init_file(input_file, data_id, 'i')
@@ -48,20 +92,18 @@ def __init__(self, input_file=None, output_file=None, data_id=None, file_prefix=
4892
self.__closed = False
4993
self.is_first_char = {}
5094

51-
def __init_file(self, f, data_id, file_type):
52-
try:
53-
is_file = isinstance(f, file)
54-
except NameError:
55-
is_file = False
56-
if isinstance(f, IOBase) or is_file:
95+
def __init_file(self, f: Union[IOBase, str, int, None],
96+
data_id: Union[int, None], file_type: str):
97+
if isinstance(f, IOBase):
5798
# consider ``f`` as a file object
5899
if file_type == 'i':
59100
self.input_file = f
60101
else:
61102
self.output_file = f
62103
elif isinstance(f, int):
63104
# consider ``f`` as a file descor
64-
self.__init_file(open(f, 'w+', newline='\n'), data_id, file_type)
105+
self.__init_file(open(f, 'w+', encoding="utf-8", newline='\n'),
106+
data_id, file_type)
65107
elif f is None:
66108
# consider wanna temp file
67109
fd, self.input_filename = tempfile.mkstemp()
@@ -75,12 +117,13 @@ def __init_file(self, f, data_id, file_type):
75117
filename = f.format(data_id or '')
76118
if file_type == 'i':
77119
self.input_filename = filename
78-
log.debug("Processing %s" % self.input_filename)
79120
else:
80121
self.output_filename = filename
81-
self.__init_file(open(filename, 'w+', newline='\n'), data_id, file_type)
122+
self.__init_file(
123+
open(filename, 'w+', newline='\n', encoding='utf-8'), data_id,
124+
file_type)
82125

83-
def __escape_format(self, st):
126+
def __escape_format(self, st: str):
84127
"""replace "{}" to "{{}}" """
85128
return re.sub(r'\{', '{{', re.sub(r'\}', '}}', st))
86129

@@ -99,7 +142,8 @@ def close(self):
99142
deleted = False
100143
try:
101144
# on posix, one can remove a file while it's opend by a process
102-
# the file then will be not visable to others, but process still have the file descriptor
145+
# the file then will be not visable to others,
146+
# but process still have the file descriptor
103147
# it is recommand to remove temp file before close it on posix to avoid race
104148
# on nt, it will just fail and raise OSError so that after closing remove it again
105149
self.__del_files()
@@ -123,12 +167,10 @@ def __enter__(self):
123167
def __exit__(self, exc_type, exc_val, exc_tb):
124168
self.close()
125169

126-
def __write(self, file, *args, **kwargs):
127-
"""__write(self, file, *args, **kwargs) -> None
128-
Write every element in *args into file. If the element isn't "\n", insert a space. It will convert every element into str
129-
file file -> the file object to write
130-
**kwargs:
131-
str separator = " " -> a string used to separate every element
170+
def __write(self, file: IOBase, *args, **kwargs):
171+
"""
172+
Write every element in *args into file. If the element isn't "\n", insert `separator`.
173+
It will convert every element into str.
132174
"""
133175
separator = kwargs.get("separator", " ")
134176
for arg in args:
@@ -143,53 +185,70 @@ def __write(self, file, *args, **kwargs):
143185
self.is_first_char[file] = True
144186

145187
def input_write(self, *args, **kwargs):
146-
"""input_write(self, *args, **kwargs) -> None
147-
Write every element in *args into the input file. Splits with spaces. It will convert every element into string
148-
**kwargs:
149-
str separator = " " -> a string used to separate every element
188+
"""
189+
Write every element in *args into the input file. Splits with `separator`.
190+
It will convert every element into str.
191+
Args:
192+
*args: the elements to write
193+
separator: a string used to separate every element. Defaults to " ".
150194
"""
151195
self.__write(self.input_file, *args, **kwargs)
152196

153197
def input_writeln(self, *args, **kwargs):
154-
"""input_writeln(self, *args, **kwargs) -> None
155-
Write every element in *args into the input file and turn to a new line. Splits with spaces. It will convert every element into string
156-
**kwargs:
157-
str separator = " " -> a string used to separate every element
198+
"""
199+
Write every element in *args into the input file and turn to a new line
200+
Splits with `separator`.
201+
It will convert every element into str.
202+
Args:
203+
*args: the elements to write
204+
separator: a string used to separate every element. Defaults to " ".
158205
"""
159206
args = list(args)
160207
args.append("\n")
161208
self.input_write(*args, **kwargs)
162209

163210
def output_gen(self, shell_cmd):
164-
"""output_gen(self, shell_cmd) -> None
165-
Run the command shell_cmd(usually the std programme) and send it the input file as stdin. Write its output to the output file.
166-
str shell_cmd -> the command to run, usually the std programme
211+
"""
212+
Run the command `shell_cmd` (usually the std program) and send it the input file as stdin.
213+
Write its output to the output file.
214+
Args:
215+
shell_cmd: the command to run, usually the std program.
167216
"""
168217
self.flush_buffer()
169218
origin_pos = self.input_file.tell()
170219
self.input_file.seek(0)
171-
subprocess.check_call(shell_cmd, shell=True, stdin=self.input_file, stdout=self.output_file, universal_newlines=True)
220+
subprocess.check_call(shell_cmd,
221+
shell=True,
222+
stdin=self.input_file,
223+
stdout=self.output_file,
224+
universal_newlines=True)
172225
self.input_file.seek(origin_pos)
173226

174227
log.debug(self.output_filename, " done")
175228

176229
def output_write(self, *args, **kwargs):
177-
"""output_write(self, *args, **kwargs) -> None
178-
Write every element in *args into the output file. Splits with spaces. It will convert every element into string
179-
**kwargs:
180-
str separator = " " -> a string used to separate every element
230+
"""
231+
Write every element in *args into the output file. Splits with `separator`.
232+
It will convert every element into str.
233+
Args:
234+
*args: the elements to write
235+
separator: a string used to separate every element. Defaults to " ".
181236
"""
182237
self.__write(self.output_file, *args, **kwargs)
183238

184239
def output_writeln(self, *args, **kwargs):
185-
"""output_writeln(self, *args, **kwargs) -> None
186-
Write every element in *args into the output file and turn to a new line. Splits with spaces. It will convert every element into string
187-
**kwargs:
188-
str separator = " " -> a string used to separate every element
240+
"""
241+
Write every element in *args into the output file and turn to a new line.
242+
Splits with `separator`.
243+
It will convert every element into str.
244+
Args:
245+
*args: the elements to write
246+
separator: a string used to separate every element. Defaults to " ".
189247
"""
190248
args = list(args)
191249
args.append("\n")
192250
self.output_write(*args, **kwargs)
193251

194252
def flush_buffer(self):
253+
"""Flush the input file"""
195254
self.input_file.flush()

cyaron/math.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
'''
1+
"""
22
This is a module that includes some useful math functions.
33
44
Functions:
@@ -27,7 +27,7 @@
2727
n2words(num,join=True): Number to words
2828
2929
forked from https://blog.dreamshire.com/common-functions-routines-project-euler/
30-
'''
30+
"""
3131

3232
from __future__ import absolute_import
3333
from math import sqrt, factorial
@@ -170,7 +170,7 @@ def fibonacci(n: int):
170170

171171

172172
def _fib(n: int) -> Tuple[int, int]:
173-
'''Returns a tuple of fibonacci (F(n), F(n+1)).'''
173+
"""Returns a tuple of fibonacci (F(n), F(n+1))."""
174174
if n == 0:
175175
return (0, 1)
176176
a, b = _fib(n // 2)

cyaron/utils.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,7 @@ def strtolines(str):
3434

3535

3636
def make_unicode(data):
37-
try:
38-
return unicode(data)
39-
except NameError:
40-
return str(data)
37+
return str(data)
4138

4239
def unpack_kwargs(funcname, kwargs, arg_pattern):
4340
rv = {}

0 commit comments

Comments
 (0)