mirror of
https://github.com/ejwa/gitinspector.git
synced 2025-03-26 02:01:27 +01:00
Ran the whole project through "pylint" and fixed violations.
Also created a custom .pylintrc file that disables a few warnings, but for the most part, gitinspector now follows proper python guidelines.
This commit is contained in:
parent
1eedd79089
commit
e5137a8468
9 changed files with 118 additions and 104 deletions
14
.pylintrc
Normal file
14
.pylintrc
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[REPORTS]
|
||||||
|
include-ids=yes
|
||||||
|
comment=yes
|
||||||
|
|
||||||
|
[MESSAGES CONTROL]
|
||||||
|
disable=C0111,W0232,W0603,W0702
|
||||||
|
|
||||||
|
|
||||||
|
[DESIGN]
|
||||||
|
min-public-methods=0
|
||||||
|
|
||||||
|
[FORMAT]
|
||||||
|
max-line-length=130
|
||||||
|
indent-string='\t'
|
17
blame.py
17
blame.py
|
@ -25,13 +25,14 @@ import terminal
|
||||||
class Blame:
|
class Blame:
|
||||||
def __init__(self, repo, hard):
|
def __init__(self, repo, hard):
|
||||||
self.blames = {}
|
self.blames = {}
|
||||||
f = sysrun.run(repo, "git ls-tree --name-only -r HEAD")
|
ls_tree_r = sysrun.run(repo, "git ls-tree --name-only -r HEAD")
|
||||||
|
|
||||||
for i in f.readlines():
|
for i in ls_tree_r.readlines():
|
||||||
if FileDiff.is_valid_extension(i):
|
if FileDiff.is_valid_extension(i):
|
||||||
g = sysrun.run(repo, "git blame -w {0} \"".format("-C -M" if hard else "") + i.strip() + "\"")
|
git_blame_r = sysrun.run(repo, "git blame -w {0} \"".format("-C -M" if hard else "") +
|
||||||
|
i.strip() + "\"")
|
||||||
|
|
||||||
for j in g.readlines():
|
for j in git_blame_r.readlines():
|
||||||
if Blame.is_blame_line(j):
|
if Blame.is_blame_line(j):
|
||||||
author = Blame.get_author(j)
|
author = Blame.get_author(j)
|
||||||
|
|
||||||
|
@ -46,15 +47,15 @@ class Blame:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_author(string):
|
def get_author(string):
|
||||||
g = re.search(" \((.*?)\d\d\d\d-\d\d-\d\d", string)
|
author = re.search(" \((.*?)\d\d\d\d-\d\d-\d\d", string)
|
||||||
return re.sub("[^\w ]", "", g.group(1)).strip()
|
return re.sub("[^\w ]", "", author.group(1)).strip()
|
||||||
|
|
||||||
def output(repo, hard):
|
def output(repo, hard):
|
||||||
b = Blame(repo, hard)
|
blame = Blame(repo, hard)
|
||||||
|
|
||||||
print "\nBelow is the number of rows from each author that have survived and"
|
print "\nBelow is the number of rows from each author that have survived and"
|
||||||
print "are still intact in the current revision:\n"
|
print "are still intact in the current revision:\n"
|
||||||
terminal.printb("Author".ljust(21) + " Rows")
|
terminal.printb("Author".ljust(21) + " Rows")
|
||||||
for i in sorted(b.blames.items()):
|
for i in sorted(blame.blames.items()):
|
||||||
print i[0].ljust(20)[0:20],
|
print i[0].ljust(20)[0:20],
|
||||||
print str(i[1]).rjust(10)
|
print str(i[1]).rjust(10)
|
||||||
|
|
37
changes.py
37
changes.py
|
@ -34,20 +34,20 @@ class FileDiff:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_filediff_line(string):
|
def is_filediff_line(string):
|
||||||
s = string.split("|")
|
string = string.split("|")
|
||||||
return s.__len__() == 2 and s[1].find("Bin") == -1
|
return string.__len__() == 2 and string[1].find("Bin") == -1
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_extension(string):
|
def get_extension(string):
|
||||||
s = string.split("|")[0].strip().strip("{}")
|
string = string.split("|")[0].strip().strip("{}")
|
||||||
return os.path.splitext(s)[1][1:]
|
return os.path.splitext(string)[1][1:]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_valid_extension(string):
|
def is_valid_extension(string):
|
||||||
s = FileDiff.get_extension(string)
|
extension = FileDiff.get_extension(string)
|
||||||
|
|
||||||
for i in extensions.get():
|
for i in extensions.get():
|
||||||
if s == i:
|
if extension == i:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -80,11 +80,11 @@ class AuthorInfo:
|
||||||
class Changes:
|
class Changes:
|
||||||
def __init__(self, repo, hard):
|
def __init__(self, repo, hard):
|
||||||
self.commits = []
|
self.commits = []
|
||||||
f = sysrun.run(repo, "git log --pretty='%ad|%t|%aN|%s' --stat=100000 --no-merges --ignore-space-change " +
|
git_log_r = sysrun.run(repo, "git log --pretty='%ad|%t|%aN|%s' --stat=100000 --no-merges --ignore-space-change " +
|
||||||
"-C {0} --date=short".format("-C" if hard else ""))
|
"-C {0} --date=short".format("-C" if hard else ""))
|
||||||
commit = None
|
commit = None
|
||||||
found_valid_extension = False
|
found_valid_extension = False
|
||||||
lines = f.readlines()
|
lines = git_log_r.readlines()
|
||||||
|
|
||||||
for i in lines:
|
for i in lines:
|
||||||
if Commit.is_commit_line(i) or i == lines[-1]:
|
if Commit.is_commit_line(i) or i == lines[-1]:
|
||||||
|
@ -105,7 +105,8 @@ class Changes:
|
||||||
def get_commits(self):
|
def get_commits(self):
|
||||||
return self.commits
|
return self.commits
|
||||||
|
|
||||||
def __modify_authorinfo__(self, authors, key, commit):
|
@staticmethod
|
||||||
|
def __modify_authorinfo__(authors, key, commit):
|
||||||
if authors.get(key, None) == None:
|
if authors.get(key, None) == None:
|
||||||
authors[key] = AuthorInfo()
|
authors[key] = AuthorInfo()
|
||||||
|
|
||||||
|
@ -117,29 +118,29 @@ class Changes:
|
||||||
def get_authorinfo_list(self):
|
def get_authorinfo_list(self):
|
||||||
authors = {}
|
authors = {}
|
||||||
for i in self.commits:
|
for i in self.commits:
|
||||||
self.__modify_authorinfo__(authors, i.author, i)
|
Changes.__modify_authorinfo__(authors, i.author, i)
|
||||||
|
|
||||||
return authors
|
return authors
|
||||||
|
|
||||||
def get_authordateinfo_list(self):
|
def get_authordateinfo_list(self):
|
||||||
authors = {}
|
authors = {}
|
||||||
for i in self.commits:
|
for i in self.commits:
|
||||||
self.__modify_authorinfo__(authors, (i.date, i.author), i)
|
Changes.__modify_authorinfo__(authors, (i.date, i.author), i)
|
||||||
|
|
||||||
return authors
|
return authors
|
||||||
|
|
||||||
changes = None
|
__changes__ = None
|
||||||
|
|
||||||
def get(repo, hard):
|
def get(repo, hard):
|
||||||
global changes
|
global __changes__
|
||||||
if changes == None:
|
if __changes__ == None:
|
||||||
changes = Changes(repo, hard)
|
__changes__ = Changes(repo, hard)
|
||||||
|
|
||||||
return changes
|
return __changes__
|
||||||
|
|
||||||
def output(repo, hard):
|
def output(repo, hard):
|
||||||
get(repo, hard)
|
get(repo, hard)
|
||||||
authorinfo_list = changes.get_authorinfo_list()
|
authorinfo_list = get(repo, hard).get_authorinfo_list()
|
||||||
total_changes = 0.0
|
total_changes = 0.0
|
||||||
|
|
||||||
for i in authorinfo_list:
|
for i in authorinfo_list:
|
||||||
|
|
|
@ -18,20 +18,19 @@
|
||||||
# along with gitinspector. If not, see <http://www.gnu.org/licenses/>.
|
# along with gitinspector. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
__default_extensions__ = ["java", "c", "cpp", "h", "hpp", "py", "glsl", "rb", "js", "sql"]
|
__default_extensions__ = ["java", "c", "cpp", "h", "hpp", "py", "glsl", "rb", "js", "sql"]
|
||||||
extensions = __default_extensions__
|
__extensions__ = __default_extensions__
|
||||||
located_extensions = set()
|
__located_extensions__ = set()
|
||||||
|
|
||||||
def get():
|
def get():
|
||||||
return extensions
|
return __extensions__
|
||||||
|
|
||||||
def set(string):
|
def define(string):
|
||||||
global extensions
|
global __extensions__
|
||||||
extensions = string.split(",")
|
__extensions__ = string.split(",")
|
||||||
|
|
||||||
def add_located(string):
|
def add_located(string):
|
||||||
if len(string) > 0:
|
if len(string) > 0:
|
||||||
global located_extensions
|
__located_extensions__.add(string)
|
||||||
located_extensions.add(string)
|
|
||||||
|
|
||||||
def get_located():
|
def get_located():
|
||||||
return located_extensions
|
return __located_extensions__
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Runner:
|
||||||
terminal.skip_escapes(self.skipescapes)
|
terminal.skip_escapes(self.skipescapes)
|
||||||
changes.output(self.repo, self.hard)
|
changes.output(self.repo, self.hard)
|
||||||
|
|
||||||
if changes.changes.get_commits():
|
if changes.get(self.repo, self.hard).get_commits():
|
||||||
blame.output(self.repo, self.hard)
|
blame.output(self.repo, self.hard)
|
||||||
|
|
||||||
if self.timeline == True:
|
if self.timeline == True:
|
||||||
|
@ -56,39 +56,40 @@ class Runner:
|
||||||
print i,
|
print i,
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
r = Runner()
|
__run__ = Runner()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.gnu_getopt(sys.argv[1:], "f:hHlTwx", ["file-types=", "hard", "help", "list-file-types", "tda367", "timeline", "version"])
|
__opts__, __args__ = getopt.gnu_getopt(sys.argv[1:], "f:hHlTwx", ["file-types=", "hard", "help",
|
||||||
|
"list-file-types", "tda367", "timeline", "version"])
|
||||||
except getopt.error, msg:
|
except getopt.error, msg:
|
||||||
print sys.argv[0], "\b:", msg
|
print sys.argv[0], "\b:", msg
|
||||||
print "Try `", sys.argv[0], "--help' for more information."
|
print "Try `", sys.argv[0], "--help' for more information."
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
for o, a in opts:
|
for o, a in __opts__:
|
||||||
if o in("-h", "--help"):
|
if o in("-h", "--help"):
|
||||||
help.output()
|
help.output()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
elif o in("-f", "--file-types"):
|
elif o in("-f", "--file-types"):
|
||||||
extensions.set(a)
|
extensions.define(a)
|
||||||
elif o in("-H", "--hard"):
|
elif o in("-H", "--hard"):
|
||||||
r.hard = True
|
__run__.hard = True
|
||||||
elif o in("-l", "--list-file-types"):
|
elif o in("-l", "--list-file-types"):
|
||||||
r.list_file_types = True
|
__run__.list_file_types = True
|
||||||
elif o in("--version"):
|
elif o in("--version"):
|
||||||
version.output()
|
version.output()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
elif o in("--tda367"):
|
elif o in("--tda367"):
|
||||||
r.list_file_types = True
|
__run__.list_file_types = True
|
||||||
r.tda367 = True
|
__run__.tda367 = True
|
||||||
r.timeline = True
|
__run__.timeline = True
|
||||||
r.useweeks = True
|
__run__.useweeks = True
|
||||||
elif o in("-T", "--timeline"):
|
elif o in("-T", "--timeline"):
|
||||||
r.timeline = True
|
__run__.timeline = True
|
||||||
elif o in("-w"):
|
elif o in("-w"):
|
||||||
r.useweeks = True
|
__run__.useweeks = True
|
||||||
elif o in("-x"):
|
elif o in("-x"):
|
||||||
r.skipescapes = True
|
__run__.skipescapes = True
|
||||||
for arg in args:
|
for arg in __args__:
|
||||||
r.repo = arg
|
__run__.repo = arg
|
||||||
|
|
||||||
r.output()
|
__run__.output()
|
||||||
|
|
|
@ -22,7 +22,7 @@ import os
|
||||||
def run(directory, command):
|
def run(directory, command):
|
||||||
previous_directory = os.getcwd()
|
previous_directory = os.getcwd()
|
||||||
os.chdir(directory)
|
os.chdir(directory)
|
||||||
f = os.popen(command)
|
result = os.popen(command)
|
||||||
os.chdir(previous_directory)
|
os.chdir(previous_directory)
|
||||||
|
|
||||||
return f
|
return result
|
||||||
|
|
49
terminal.py
49
terminal.py
|
@ -17,25 +17,26 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with gitinspector. If not, see <http://www.gnu.org/licenses/>.
|
# along with gitinspector. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
bold = "\033[1m"
|
__bold__ = "\033[1m"
|
||||||
normal = "\033[0;0m"
|
__normal__ = "\033[0;0m"
|
||||||
|
|
||||||
def __get_size_windows__():
|
def __get_size_windows__():
|
||||||
res=None
|
res = None
|
||||||
try:
|
try:
|
||||||
from ctypes import windll, create_string_buffer
|
from ctypes import windll, create_string_buffer
|
||||||
|
|
||||||
h = windll.kernel32.GetStdHandle(-12) # stderr
|
handler = windll.kernel32.GetStdHandle(-12) # stderr
|
||||||
csbi = create_string_buffer(22)
|
csbi = create_string_buffer(22)
|
||||||
res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
|
res = windll.kernel32.GetConsoleScreenBufferInfo(handler, csbi)
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if res:
|
if res:
|
||||||
import struct
|
import struct
|
||||||
(bufx, bufy, curx, cury, wattr, left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
|
(_, _, _, _, _, left, top, right, bottom, _, _) = struct.unpack("hhhhHhhhhhh", csbi.raw)
|
||||||
sizex = right - left + 1
|
sizex = right - left + 1
|
||||||
sizey = bottom - top + 1
|
sizey = bottom - top + 1
|
||||||
return sizex, sizey
|
return sizex, sizey
|
||||||
|
@ -45,7 +46,7 @@ def __get_size_windows__():
|
||||||
def __get_size_tput__():
|
def __get_size_tput__():
|
||||||
try:
|
try:
|
||||||
import subprocess
|
import subprocess
|
||||||
proc=subprocess.Popen(["tput", "cols"], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
|
proc = subprocess.Popen(["tput", "cols"], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
|
||||||
output = proc.communicate(input = None)
|
output = proc.communicate(input = None)
|
||||||
cols = int(output[0])
|
cols = int(output[0])
|
||||||
proc = subprocess.Popen(["tput", "lines"], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
|
proc = subprocess.Popen(["tput", "lines"], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
|
||||||
|
@ -56,41 +57,41 @@ def __get_size_tput__():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __get_size_linux__():
|
def __get_size_linux__():
|
||||||
def ioctl_GWINSZ(fd):
|
def ioctl_get_window_size(file_descriptor):
|
||||||
try:
|
try:
|
||||||
import fcntl, termios, struct, os
|
import fcntl, termios, struct
|
||||||
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
|
size = struct.unpack('hh', fcntl.ioctl(file_descriptor, termios.TIOCGWINSZ, '1234'))
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return cr
|
return size
|
||||||
|
|
||||||
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
|
size = ioctl_get_window_size(0) or ioctl_get_window_size(1) or ioctl_get_window_size(2)
|
||||||
|
|
||||||
if not cr:
|
if not size:
|
||||||
try:
|
try:
|
||||||
fd = os.open(os.ctermid(), os.O_RDONLY)
|
file_descriptor = os.open(os.ctermid(), os.O_RDONLY)
|
||||||
cr = ioctl_GWINSZ(fd)
|
size = ioctl_get_window_size(file_descriptor)
|
||||||
os.close(fd)
|
os.close(file_descriptor)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if not cr:
|
if not size:
|
||||||
try:
|
try:
|
||||||
cr = (env['LINES'], env['COLUMNS'])
|
size = (os.environ["LINES"], os.environ["COLUMNS"])
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return int(cr[1]), int(cr[0])
|
return int(size[1]), int(size[0])
|
||||||
|
|
||||||
def skip_escapes(skip):
|
def skip_escapes(skip):
|
||||||
if skip:
|
if skip:
|
||||||
global bold
|
global __bold__
|
||||||
global normal
|
global __normal__
|
||||||
bold = ""
|
__bold__ = ""
|
||||||
normal = ""
|
__normal__ = ""
|
||||||
|
|
||||||
def printb(string):
|
def printb(string):
|
||||||
print bold + string + normal
|
print __bold__ + string + __normal__
|
||||||
|
|
||||||
def get_size():
|
def get_size():
|
||||||
current_os = platform.system()
|
current_os = platform.system()
|
||||||
|
|
47
timeline.py
47
timeline.py
|
@ -42,17 +42,18 @@ class TimelineData:
|
||||||
self.entries[key].insertions += i[1].insertions
|
self.entries[key].insertions += i[1].insertions
|
||||||
self.entries[key].deletions += i[1].deletions
|
self.entries[key].deletions += i[1].deletions
|
||||||
|
|
||||||
for p in self.get_periods():
|
for period in self.get_periods():
|
||||||
total_insertions = 0
|
total_insertions = 0
|
||||||
total_deletions = 0
|
total_deletions = 0
|
||||||
|
|
||||||
for a in self.get_authors():
|
for author in self.get_authors():
|
||||||
e = self.entries.get((a, p), None)
|
entry = self.entries.get((author, period), None)
|
||||||
if e != None:
|
if entry != None:
|
||||||
total_insertions += e.insertions
|
total_insertions += entry.insertions
|
||||||
total_deletions += e.deletions
|
total_deletions += entry.deletions
|
||||||
|
|
||||||
self.total_changes_by_period[p] = (total_insertions, total_deletions, total_insertions + total_deletions)
|
self.total_changes_by_period[period] = (total_insertions, total_deletions,
|
||||||
|
total_insertions + total_deletions)
|
||||||
|
|
||||||
def get_periods(self):
|
def get_periods(self):
|
||||||
return sorted(set([i[1] for i in self.entries]))
|
return sorted(set([i[1] for i in self.entries]))
|
||||||
|
@ -62,8 +63,6 @@ class TimelineData:
|
||||||
|
|
||||||
def get_author_signs_in_period(self, author, period, multiplier):
|
def get_author_signs_in_period(self, author, period, multiplier):
|
||||||
authorinfo = self.entries.get((author, period), None)
|
authorinfo = self.entries.get((author, period), None)
|
||||||
insertions = float(self.total_changes_by_period[period][0])
|
|
||||||
deletions = float(self.total_changes_by_period[period][1])
|
|
||||||
total = float(self.total_changes_by_period[period][2])
|
total = float(self.total_changes_by_period[period][2])
|
||||||
|
|
||||||
if authorinfo:
|
if authorinfo:
|
||||||
|
@ -78,11 +77,11 @@ class TimelineData:
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
for i in self.entries:
|
for i in self.entries:
|
||||||
e = self.entries.get(i)
|
entry = self.entries.get(i)
|
||||||
|
|
||||||
if period == i[1]:
|
if period == i[1]:
|
||||||
deletions = e.deletions / float(self.total_changes_by_period[i[1]][2])
|
changes_in_period = float(self.total_changes_by_period[i[1]][2])
|
||||||
if multiplier * (e.insertions + e.deletions) / float(self.total_changes_by_period[i[1]][2]) > max_width:
|
if multiplier * (entry.insertions + entry.deletions) / changes_in_period > max_width:
|
||||||
return multiplier
|
return multiplier
|
||||||
|
|
||||||
multiplier += 0.25
|
multiplier += 0.25
|
||||||
|
@ -90,21 +89,21 @@ class TimelineData:
|
||||||
def is_author_in_period(self, period, author):
|
def is_author_in_period(self, period, author):
|
||||||
return self.entries.get((author, period), None) != None
|
return self.entries.get((author, period), None) != None
|
||||||
|
|
||||||
def __output_row__(changes, timeline_data, periods, names):
|
def __output_row__(timeline_data, periods, names):
|
||||||
print "\n" + terminal.bold + "Author".ljust(20),
|
print "\n" + terminal.__bold__ + "Author".ljust(20),
|
||||||
|
|
||||||
for p in periods:
|
for period in periods:
|
||||||
print p.rjust(10),
|
print period.rjust(10),
|
||||||
|
|
||||||
print terminal.normal
|
print terminal.__normal__
|
||||||
|
|
||||||
for n in names:
|
for name in names:
|
||||||
print n.ljust(20)[0:20],
|
print name.ljust(20)[0:20],
|
||||||
for p in periods:
|
for period in periods:
|
||||||
multiplier = timeline_data.get_multiplier(p, 9)
|
multiplier = timeline_data.get_multiplier(period, 9)
|
||||||
signs = timeline_data.get_author_signs_in_period(n, p, multiplier)
|
signs = timeline_data.get_author_signs_in_period(name, period, multiplier)
|
||||||
signs_str = (signs[1] * "-" + signs[0] * "+")
|
signs_str = (signs[1] * "-" + signs[0] * "+")
|
||||||
print ("." if timeline_data.is_author_in_period(p, n) and len(signs_str) == 0 else signs_str).rjust(10),
|
print ("." if timeline_data.is_author_in_period(period, name) and len(signs_str) == 0 else signs_str).rjust(10),
|
||||||
print ""
|
print ""
|
||||||
|
|
||||||
def output(changes, useweeks):
|
def output(changes, useweeks):
|
||||||
|
@ -118,4 +117,4 @@ def output(changes, useweeks):
|
||||||
max_periods_per_row = (width - 21) / 11
|
max_periods_per_row = (width - 21) / 11
|
||||||
|
|
||||||
for i in range(0, len(periods), max_periods_per_row):
|
for i in range(0, len(periods), max_periods_per_row):
|
||||||
__output_row__(changes, timeline_data, periods[i:i+max_periods_per_row], names)
|
__output_row__(timeline_data, periods[i:i+max_periods_per_row], names)
|
||||||
|
|
|
@ -25,8 +25,6 @@ There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
|
||||||
Written by Adam Waldenberg."""
|
Written by Adam Waldenberg."""
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
__version__ = "0.0.1"
|
__version__ = "0.0.1"
|
||||||
|
|
||||||
def output():
|
def output():
|
||||||
|
|
Loading…
Add table
Reference in a new issue