import os, sysimport sqlite3from enum import Enum
class Listkeeper(object): def __init__(self): self.file = str() for i in os.listdir("."): if i.endswith(".lst"): self.file = i if len(self.file) == 0: name = self.get_string("Please enter list name", "Name") if str(name).endswith(".lst"): self.file = name else: self.file = name + ".lst" assert len(self.file) > 0 if not os.path.exists(self.file): with open(self.file, 'w') as f: f.write('')
def get_string(self, message, name="String", default=None, min_len=0, max_len=50): message += ": " if default is None else "[{}]: ".format(default) while True: try: line = input(message) if not line: if default is not None: return default else: raise ValueError("{} can not be empty".format(name)) if min_len > len(line) or len(line) > max_len: raise ValueError("{} length must between {} and {} characters".format(name, min_len, max_len)) return line except ValueError as err: print(err)
def select(self, default=None): if default: for i in enumerate(default, start=1): print("{}: {}".format(i[0], i[1].strip('\n'))) while True: try: selection = self.get_string("Select option in (A)dd (D)elete (S)ave (Q)uit") if selection not in ('A', 'a', 'D', 'd', 'S', 's', 'Q', 'q'): raise ValueError("{} is not a valid option".format(selection)) else: return selection except ValueError as err: print(err)
def list_items(self, list): with open(list, 'r') as f: contents = f.readlines() return contents
def add_item(self, list, value): list.append(value) return sorted(list)
def rm_item(self, list, index): if index == 0: return list list.pop(index - 1) return list
def save(self, file, list): with open(file, 'w') as f: f.flush() for line in list: f.write(line.strip('\n') + '\n')
if __name__ == "__main__": managedList = Listkeeper() itemList = list(managedList.list_items(managedList.file)) while True: select = managedList.select(itemList) if select in ('A', 'a'): item = managedList.get_string("Add item", "List item", default=None, min_len=2) itemList = managedList.add_item(itemList, item) if select in ('D', 'd'): itemIndex = int(managedList.get_string("Delete item number ( '0' to cancel)")) itemList = managedList.rm_item(itemList, itemIndex) if select in ('S', 's'): managedList.save(managedList.file, itemList) if select in ('Q', 'q'): if itemList != managedList.list_items(managedList.file): while True: save = managedList.get_string("Quit without saving[y/n]?") if save in ('Y', 'y'): print("Changes have not been saved") sys.exit() else: print("Changes have been saved") managedList.save(managedList.file, itemList) sys.exit() else: sys.exit()SO I WANT TO TRY AND ADD THE CODE WHICH IS IN THE SECOND ASSIGNMENT TO THE FIRST ONE CAN YOU HELP?
import osimport sqlite3from enum import Enum
def get_string(self, message, name="String", default=None, min_len=0, max_len=50): message += ": " if default is None else "[{}]: ".format(default) while True: try: line = input(message) if not line: if default is not None: return default else: raise ValueError("{} can not be empty".format(name)) if min_len > len(line) or len(line) > max_len: raise ValueError("{} length must between {} and {} characters".format(name, min_len, max_len)) return line except ValueError as err: print(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 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))
class Files(object): """Class to manage all file I/O""" connection = None
def __init__(self): #super(, self).__init__() #self.arg = arg self.fnames = [e for e in os.listdir() if e.endswith(".db")] self.name = ""
def list(self): return self.fnames
def open(self, name): self.connection = sqlite3.connect(name)
def set(self, newname): self.connection = sqlite3.connect(newname) cursor = self.connection.cursor() sql_command = """ CREATE TABLE thelist ( item_number INTEGER PRIMARY KEY, item_name VARCHAR(20));""" cursor.execute(sql_command) self.connection.commit()
def load(self, newname): items = [] cursor = self.connection.cursor() cursor.execute("SELECT * FROM thelist") result = cursor.fetchall() for l in result: items.append(l[1]) return items
#def save(self, items): # f_handle = open(self.name, "w") # for l in items: # f_handle.write(l + "\n") # f_handle.close() def add(self, item): cursor = self.connection.cursor() format_str = """INSERT INTO thelist (item_number, item_name) VALUES (NULL, "{name}");""" sql_command = format_str.format(name = item) cursor.execute(sql_command) self.connection.commit()
def delete(self, item): cursor = self.connection.cursor() format_str = """DELETE FROM thelist WHERE item_name = "{name}";""" sql_command = format_str.format(name=item) cursor.execute(sql_command) self.connection.commit()
def close(self): self.connection.close()
class State(Enum): """List of the states the program can be in""" empty = 1 # messages for empty list main = 2 # display & edit populated list add = 3 # add an item to the list delete = 4 # remove an item from the list quit = 5 # close the connection finished = 6 # only flags halt to main loop
class Actions(object): """State machine to manage input and output"""
def __init__(self): # setup state info self.file = Files() # get the file name & contents names = self.file.fnames if self.file.fnames: # if there are files to choose from self.show_list(names) digit = get_integer("Load file number (or 0 for new file)", minimum=0, maximum=len(names)) if digit != 0: # chosen file is loaded self.file.open(names[digit-1]) self.items = self.file.load(names[digit-1]) if self.items: self.current = State.main # start with items displayed return else: self.current = State.empty # start with empty notice
# user chooses a new filename self.items = [] newname = get_string("Choose filename", minimum_length=2, maximum_length=80) if not newname.endswith(".db"): newname += ".db" self.file.name = newname self.file.set(newname) self.current = State.empty
def show_list(self, in_list): """Helper function to show a numbered list""" i = 1 for e in in_list: print(str(i) + ": " + e) i += 1
def process(self, options): """Request & processes user input, then set next state as appropriate""" ok = False while not ok: qstr = "" opts = "" for c in options: if c == "a": qstr += "[A]dd" opts += "Aa" elif c == "d": qstr += " [D]elete" opts += "Dd" elif c == "q": qstr += " [Q]uit" opts += "Qq" ans = get_string(qstr, default="a", minimum_length=1, maximum_length=1).lower() if ans == "a": self.current = State.add ok = True elif ans == "d": self.current = State.delete ok = True elif ans == "q": self.current = State.quit ok = True else: print("ERROR: invalid choice--enter one of '" + opts + "'")
def next(self): if self.current == State.empty: # shows the empty list message, add only print("--no items are in the list--") self.process("aq") elif self.current == State.main: # shows list with add & delete options self.show_list(self.items) self.process("adq") elif self.current == State.add: # handles adding adding an item new = get_string("Add item") self.items.insert(0,new) self.items.sort(key=str.lower) self.file.add(new) self.current = State.main elif self.current == State.delete: # handles deleting an item digit = get_integer("Delete item number (or 0 to cancel)", minimum=0, maximum=len(self.items)) if digit != 0: self.file.delete(self.items[digit - 1]) self.items.pop(digit - 1) if not self.items: self.current = State.empty return self.current = State.main elif self.current == State.quit: # asks & handles saving before 'finished' self.file.close() self.current = State.finished elif self.current == State.finished: pass # only used to flag quitting to the main loop
# the main loop# repeatedly runs the state machine until the 'finished' statethestate = Actions()while thestate.current != State.finished: thestate.next()