diff --git a/Programming_in_Python3/Examples/Listkeeper.py b/Programming_in_Python3/Examples/Listkeeper.py new file mode 100755 index 0000000..19e2a14 --- /dev/null +++ b/Programming_in_Python3/Examples/Listkeeper.py @@ -0,0 +1,237 @@ +#!/usr/bin/env python3 + +import os, sys + +def get_string(message, name="string", default=None, + minimum_length=0, maximum_length=80): + message += ": " if default is None else " [{0}]: ".format(default) + while True: + try: + line = input(message) + if not line: + if default is not None: + return default + if minimum_length == 0: + return "" + else: + raise ValueError("{0} may not be empty".format( + name)) + if not (minimum_length <= len(line) <= maximum_length): + raise ValueError("{name} must have at least " + "{minimum_length} and at most " + "{maximum_length} characters".format( + **locals())) + return line + except ValueError as err: + print("ERROR", err) + + +def get_integer(message, name="integer", default=None, minimum=0, + maximum=100, allow_zero=True): + + class RangeError(Exception): pass + + message += ": " if default is None else " [{0}]: ".format(default) + while True: + try: + line = input(message) + if not line and default is not None: + return default + i = int(line) + if i == 0: + if allow_zero: + return i + else: + raise RangeError("{0} may not be 0".format(name)) + if not (minimum <= i <= maximum): + raise RangeError("{name} must be between {minimum} " + "and {maximum} inclusive{0}".format( + " (or 0)" if allow_zero else "", **locals())) + return i + except RangeError as err: + print("ERROR", err) + except ValueError as err: + print("ERROR {0} must be an integer".format(name)) + +def main(): + dir_list = os.listdir(".") + dir_list_lst = list() + for i in sorted(dir_list): + if i.endswith(".lst"): + dir_list_lst.append(i) + for i in sorted(dir_list_lst): + print ("{0}.{1}".format(sorted(dir_list_lst).index(i)+1, i)) + if dir_list_lst: + try: + file_number = get_integer("Choose file from 0(new file) to {0}".format(len(dir_list_lst)), maximum=len(dir_list_lst), default=1) + filename = dir_list_lst[file_number-1] if file_number else get_name() + cur_list = load_list(filename) if file_number else list() + if cur_list: + modified = 0 + list_list(cur_list) + while True: + option = get_option(("[A]dd [Q]uit [a]: "), add='a', quit='q', default='a') if not modified else get_option(("[A]dd [D]elete [S]ave [Q]uit [a]: "), add='a', quit='q', delete='d', save='s', default='a') + if option == 'a': + cur_list.append(get_string("Add item")) + modified = 1 + list_list(cur_list) + elif option == 's': + write_file(filename, cur_list) + elif option == 'd': + delete_item = get_integer("Delete item number (or 0 to cancel)", maximum=len(cur_list)) + if delete_item: + cur_list = del_item(cur_list, delete_item) + list_list(sorted(cur_list)) + else: + next + elif option == 'q': + if modified: + answer = get_string("Save unsaved changes (y/n)", default="y") + if answer.lower() == 'y': + write_file(filename, cur_list) + modified = 0 + elif answer.lower() == 'n': + break + else: + break + else: + print("-- no items are in the list --") + modified = 0 + while True: + option = get_option(("[A]dd [Q]uit [a]: "), add='a', quit='q', default='a') if not modified else get_option(("[A]dd [D]elete [S]ave [Q]uit [a]: "), add='a', quit='q', delete='d', save='s', default='a') + if option == 'a': + cur_list.append(get_string("Add item")) + modified = 1 + list_list(cur_list) + elif option == 's': + write_file(filename, cur_list) + modified = 0 + elif option == 'd': + delete_item = get_integer("Delete item number (or 0 to cancel)", maximum=len(cur_list)) + if delete_item: + cur_list = del_item(cur_list, delete_item) + list_list(sorted(cur_list)) + else: + next + elif option == 'q': + if modified: + answer = get_string("Save unsaved changes (y/n)", default="y") + if answer.lower() == 'y': + write_file(filename, cur_list) + modified = 0 + elif answer.lower() == 'n': + break + else: + break + except: + pass + else: + filename = get_name() + cur_list = [] + modified = 0 + list_list(cur_list) + while True: + option = get_option(("[A]dd [Q]uit [a]: "), add='a', quit='q', default='a') if not modified else get_option(("[A]dd [D]elete [S]ave [Q]uit [a]: "), add='a', quit='q', delete='d', save='s', default='a') + if option == 'a': + cur_list.append(get_string("Add item")) + modified = 1 + list_list(cur_list) + elif option == 's': + write_file(filename, cur_list) + elif option == 'd': + delete_item = get_integer("Delete item number (or 0 to cancel)", maximum=len(cur_list)) + if delete_item: + cur_list = del_item(cur_list, delete_item) + list_list(sorted(cur_list)) + else: + next + elif option == 'q': + if modified: + answer = get_string("Save unsaved changes (y/n)", default="y") + if answer.lower() == 'y': + write_file(filename, cur_list) + modified = 0 + elif answer.lower() == 'n': + break + else: + break + +def get_name(): + message = "Choose filename: " + #fh = None + while True: + try: + line = input(message) + if line.endswith(".lst"): + return line + else: + line += ".lst" + return line + except ValueError: + pass + +def get_option(args, add="", delete="", quit="", save="", default="a"): + class InvalidKey(Exception): pass + while True: + try: + option = input("{0}".format(args)) + if option.lower() == '': + return default.lower() + if option.lower() not in add and option.lower() not in delete and option.lower() not in quit and option.lower() not in save: + raise InvalidKey("ERROR: invalid choice--enter one of: {0}{1}{2}{3}{4}{5}{6}{7}".format(add.upper(), add, delete.upper(), delete, quit.upper(), quit, save.upper(), save)) + else: + return option.lower() + except InvalidKey as err: + print(err) + + +def list_file(filename): + fh = None + try: + fh = open(filename, "r") + for i, line in enumerate(sorted(fh), 1): + print("{0}.{1}".format(i, line)) + except EnvironmentError as err: + print("ERROR", err) + finally: + if fh is not None: + fh.close() + +def list_list(lst): + for i, line in enumerate(sorted(lst), 1): + print("{0}.{1}".format(i, line)) + +def load_list(filename): + fh = None + l = list() + try: + fh = open(filename, "r") + for i in fh: + l.append(i) + return l + except EnvironmentError as err: + print("ERROR", err) + finally: + if fh is not None: + fh.close() + +def del_item(lst, number_to_delete): + del lst[number_to_delete-1] + return lst + +def write_file(filename, lst): + fh = None + l = list() + try: + fh = open(filename, "w+") + for i in lst: + fh.write(i+"\n") + print("Saved {0} items to {1}".format(len(lst), filename)) + except EnvironmentError as err: + print("ERROR", err) + finally: + if fh is not None: + fh.close() + + +main() \ No newline at end of file diff --git a/Programming_in_Python3/Examples/Ls.py b/Programming_in_Python3/Examples/Ls.py new file mode 100755 index 0000000..d3ea073 --- /dev/null +++ b/Programming_in_Python3/Examples/Ls.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 + +import optparse +import os +import time +import locale +locale.setlocale(locale.LC_ALL, "") + +def main(): + parser = optparse.OptionParser("Usage: ls.py [options] [path1 [path2 [... pathN]]]") + parser.add_option("-H", "--hidden", action="store_true", dest="hidden", + help='show hidden files') + parser.add_option("-m", "--modified", action="store_true", dest="modified", + help='show last modified date/time') + parser.add_option("-o", "--order", type='choice', choices=['name', 'n', 'modified', 'm', 'size', 's'], dest="order", default="name", + help="order by ('name', 'n', 'modified', 'm', 'size', 's')[default: name]") + parser.add_option("-r", "--recursive", action="store_true", dest="recursive", + help='recurse into subdirectories [default: off]') + parser.add_option("-s", "--size", action="store_true", dest="size", + help='show sizes [default: off]') + opts, args = parser.parse_args() + if not args: + args = ['./'] + else: + for i in args: + if not i.endswith('/'): + args[args.index(i)] += "/" + + if opts.order in ['m', 'modified']: + mod = 'date' + elif opts.order in ['s', 'size']: + mod = 'size' + else: + mod = 'name' + line_keys = [] + if not opts.recursive: + for n in args: + for i in os.listdir(n): + if opts.hidden: + info = { + 'name': i, + 'size': (os.path.getsize(n+i)), + 'date': (time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(os.path.getmtime(n+i)))) + } + line_keys.append(info) + else: + if i.startswith('.'): + continue + else: + info = { + 'name': i, + 'size': (os.path.getsize(n+i)), + 'date': (time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(os.path.getmtime(n+i)))) + } + line_keys.append(info) + else: + for i in args: + for root, dirs, files in os.walk(i): + gen1 = (x for x in dirs) + if opts.hidden: + for n in gen1: + info = { + 'name': root + (n if root.endswith('/') else '/'+n), + 'size': (os.path.getsize(root + (n if root.endswith('/') else '/'+n))), + 'date': (time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(os.path.getmtime(root + (n if root.endswith('/') else '/'+n))))) + } + line_keys.append(info) + #gen = (x for x in files if os.path.isfile(x) or os.path.isdir(x)) + for n in files: + info = { + 'name': root + (n if root.endswith('/') else '/'+n), + 'size': (os.path.getsize(root + (n if root.endswith('/') else '/'+n))), + 'date': (time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(os.path.getmtime(root + (n if root.endswith('/') else '/'+n))))) + } + line_keys.append(info) + else: + for n in gen1: + if n.startswith('.'): + continue + else: + info = { + 'name': root + (n if root.endswith('/') else '/'+n), + 'size': (os.path.getsize(root + (n if root.endswith('/') else '/'+n))), + 'date': (time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(os.path.getmtime(root + (n if root.endswith('/') else '/'+n))))) + } + line_keys.append(info) + for n in files: + if n.startswith('.'): + continue + else: + info = { + 'name': root + (n if root.endswith('/') else '/'+n), + 'size': (os.path.getsize(root + (n if root.endswith('/') else '/'+n))), + 'date': (time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(os.path.getmtime(root + (n if root.endswith('/') else '/'+n))))) + } + line_keys.append(info) + + # print(line_keys) + + if line_keys: + max_size = len(str(max(line_keys, key=lambda x: x['size']).get('size'))) + else: + max_size = 0 + if opts.size and opts.modified: + print_format = '{date} {size:>{ln}n} {name}' + elif opts.size: + print_format = '{size:>{ln}n} {name}' + elif opts.modified: + print_format = '{date} {name}' + else: + print_format = '{name}' + for i in sorted(line_keys, key=lambda x: x[mod]): + print(print_format.format(**i,ln=max_size+1)) +main() \ No newline at end of file diff --git a/Programming_in_Python3/Examples/csv2html.py b/Programming_in_Python3/Examples/csv2html.py deleted file mode 100755 index ae5f3c5..0000000 --- a/Programming_in_Python3/Examples/csv2html.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2008-11 Qtrac Ltd. All rights reserved. -# This program or module is free software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. It is provided for educational -# purposes and is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. - -import sys - - -def main(): - maxwidth = 100 - print_start() - count = 0 - while True: - try: - line = input() - if count == 0: - color = "lightgreen" - elif count % 2: - color = "white" - else: - color = "lightyellow" - print_line(line, color, maxwidth) - count += 1 - except EOFError: - break - print_end() - - -def print_start(): - print("") - - -def print_line(line, color, maxwidth): - print("".format(color)) - fields = extract_fields(line) - for field in fields: - if not field: - print("") - else: - number = field.replace(",", "") - try: - x = float(number) - print("".format(round(x))) - except ValueError: - field = field.title() - field = field.replace(" And ", " and ") - if len(field) <= maxwidth: - field = escape_html(field) - else: - field = "{0} ...".format( - escape_html(field[:maxwidth])) - print("".format(field)) - print("") - - -def extract_fields(line): - fields = [] - field = "" - quote = None - for c in line: - if c in "\"'": - if quote is None: # start of quoted string - quote = c - elif quote == c: # end of quoted string - quote = None - else: - field += c # other quote inside quoted string - continue - if quote is None and c == ",": # end of a field - fields.append(field) - field = "" - else: - field += c # accumulating a field - if field: - fields.append(field) # adding the last field - return fields - - -def escape_html(text): - text = text.replace("&", "&") - text = text.replace("<", "<") - text = text.replace(">", ">") - return text - - -def print_end(): - print("
{0:d}{0}
") - - -main() diff --git a/Programming_in_Python3/Examples/generate_usernames.py b/Programming_in_Python3/Examples/generate_usernames.py index 9960922..af53058 100755 --- a/Programming_in_Python3/Examples/generate_usernames.py +++ b/Programming_in_Python3/Examples/generate_usernames.py @@ -58,22 +58,27 @@ def generate_username(fields, usernames): def print_users(users): - namewidth = 32 + namewidth = 17 usernamewidth = 9 - print("{0:<{nw}} {1:^6} {2:{uw}}".format( + print("{0:<{nw}} {1:^6} {2:{uw}} {0:<{nw}} {1:^6} {2:{uw}}".format( "Name", "ID", "Username", nw=namewidth, uw=usernamewidth)) - print("{0:-<{nw}} {0:-<6} {0:-<{uw}}".format( + print("{0:-<{nw}} {0:-<6} {0:-<{uw}} {0:-<{nw}} {0:-<6} {0:-<{uw}}".format( "", nw=namewidth, uw=usernamewidth)) - + name = [] for key in sorted(users): user = users[key] initial = "" if user.middlename: initial = " " + user.middlename[0] - name = "{0.surname}, {0.forename}{1}".format(user, initial) - print("{0:.<{nw}} ({1.id:4}) {1.username:{uw}}".format( - name, user, nw=namewidth, uw=usernamewidth)) - + name.append("{0.surname} {0.forename}{1}, ({2.id:4}), {2.username:{uw}}".format(user, initial, user, uw=usernamewidth).split(",")) + page = 0 + for i in range(len(name)-1): + print("{0[0]:.<{nw}.{nw}}{0[1]}{0[2]} {1[0]:.<{nw}.{nw}}{1[1]}{1[2]}".format( name[i], name[i+1], nw=namewidth, uw=usernamewidth)) + page += 1 + if page % 64 == 0: + print("{0:<{nw}} {1:^6} {2:{uw}} {0:<{nw}} {1:^6} {2:{uw}}".format("Name", "ID", "Username", nw=namewidth, uw=usernamewidth)) + print("{0:-<{nw}} {0:-<6} {0:-<{uw}} {0:-<{nw}} {0:-<6} {0:-<{uw}}".format("", nw=namewidth, uw=usernamewidth)) + #print(name) main() diff --git a/Programming_in_Python3/Examples/print_unicode.py b/Programming_in_Python3/Examples/print_unicode.py index a153493..4164be6 100755 --- a/Programming_in_Python3/Examples/print_unicode.py +++ b/Programming_in_Python3/Examples/print_unicode.py @@ -8,12 +8,11 @@ # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. - import sys import unicodedata -def print_unicode_table(word): +def print_unicode_table(words): print("decimal hex chr {0:^40}".format("name")) print("------- ----- --- {0:-<40}".format("")) @@ -23,18 +22,19 @@ def print_unicode_table(word): while code < end: c = chr(code) name = unicodedata.name(c, "*** unknown ***") - if word is None or word in name.lower(): + if words != None: + words = [item.upper() for item in words] + if words is None or sorted(list(set(words) & set(name.split()))) == sorted(words): print("{0:7} {0:5X} {0:^3c} {1}".format( - code, name.title())) + code, name.title())) code += 1 - -word = None +words = None if len(sys.argv) > 1: if sys.argv[1] in ("-h", "--help"): print("usage: {0} [string]".format(sys.argv[0])) - word = 0 + words = 0 else: - word = sys.argv[1].lower() -if word != 0: - print_unicode_table(word) + words = sys.argv[1:] +if words != 0: + print_unicode_table(words) diff --git a/Programming_in_Python3/Examples/quadratic.py b/Programming_in_Python3/Examples/quadratic.py index 44f44c0..e15d95c 100755 --- a/Programming_in_Python3/Examples/quadratic.py +++ b/Programming_in_Python3/Examples/quadratic.py @@ -47,6 +47,31 @@ def get_float(msg, allow_zero): equation = ("{0}x\N{SUPERSCRIPT TWO} + {1}x + {2} = 0" " \N{RIGHTWARDS ARROW} x = {3}").format(a, b, c, x1) +if a < 0: + equation = ("-{0}x\N{SUPERSCRIPT TWO} + {1}x + {2} = 0" + " \N{RIGHTWARDS ARROW} x = {3}").format(abs(a), b, c, x1) +if b < 0: + equation = ("{0}x\N{SUPERSCRIPT TWO} - {1}x + {2} = 0" + " \N{RIGHTWARDS ARROW} x = {3}").format(a, abs(b), c, x1) +if c < 0: + equation = ("{0}x\N{SUPERSCRIPT TWO} + {1}x - {2} = 0" + " \N{RIGHTWARDS ARROW} x = {3}").format(a, b, abs(c), x1) +if a < 0 and b < 0: + equation = ("-{0}x\N{SUPERSCRIPT TWO} - {1}x + {2} = 0" + " \N{RIGHTWARDS ARROW} x = {3}").format(abs(a), abs(b), c, x1) +if a < 0 and c < 0: + equation = ("-{0}x\N{SUPERSCRIPT TWO} + {1}x - {2} = 0" + " \N{RIGHTWARDS ARROW} x = {3}").format(abs(a), b, abs(c), x1) +if b < 0 and c < 0: + equation = ("{0}x\N{SUPERSCRIPT TWO} - {1}x - {2} = 0" + " \N{RIGHTWARDS ARROW} x = {3}").format(a, abs(b), abs(c), x1) +if a < 0 and b < 0 and c < 0: + equation = ("-{0}x\N{SUPERSCRIPT TWO} - {1}x - {2} = 0" + " \N{RIGHTWARDS ARROW} x = {3}").format(abs(a), abs(b), abs(c), x1) + + if x2 is not None: equation += " or x = {0}".format(x2) +elif x2 is not None and x2 < 0: + equation += " or x = -{0}".format(abs(x2)) print(equation) diff --git a/Programming_in_Python3/Examples/uniquewords2.py b/Programming_in_Python3/Examples/uniquewords2.py index c0e90ad..bb22c48 100755 --- a/Programming_in_Python3/Examples/uniquewords2.py +++ b/Programming_in_Python3/Examples/uniquewords2.py @@ -22,5 +22,5 @@ word = word.strip(strip) if len(word) > 2: words[word] += 1 -for word in sorted(words): +for word in sorted(words, key=lambda val: words.get(val)): print("'{0}' occurs {1} times".format(word, words[word]))