diff --git a/chk_for_22.py b/chk_for_22.py new file mode 100644 index 0000000..37b7b9d --- /dev/null +++ b/chk_for_22.py @@ -0,0 +1,34 @@ + +def has22(lst): + + """ + Test to determine if there are two adjacent 2s in a passed in list + >>> x = [0, 1, 4, 2, 2, 3] + >>> has22(x) + True + >>> + >>> y = [0, 1, 2, 3, 4, 5] + >>> has22(y) + False + >>> + >>> z = "122345" + >>> has22(z) + True + >>> + """ + + # Initialize counter + cnt = 0 + + try: + # Run through list + for x in lst: + if str(x) == "2" and str(lst[cnt + 1]) == "2": + return True + cnt += 1 + except: + return False + +if __name__ == "__main__": + var = [1,2,2,3,4,2] + print(has22(var)) diff --git a/count13.py b/count13.py new file mode 100644 index 0000000..fdf54e2 --- /dev/null +++ b/count13.py @@ -0,0 +1,17 @@ + +def count13(lst): + """ + Sum all numbers in a passed in list that are less than 13 + >>> count13([1,2,5,7,8,13,15,20]) + 23 + >>> + """ + if not type(lst) is list: + return 0 + good_lst = [x for x in lst if type(x) is int or type(x) is float] + return sum([x for x in good_lst if x < 13]) + +if __name__ == "__main__": + lst = [1,2,5,7,8,13,15,20] + print(count13(lst)) + \ No newline at end of file diff --git a/count_evens.py b/count_evens.py new file mode 100644 index 0000000..b4c86d9 --- /dev/null +++ b/count_evens.py @@ -0,0 +1,23 @@ + +def count_evens(lst): + """ + Determines the number of even integers in a passed in list of integers + Example: count_evens([1,2,3,4]) would return 2 + >>> count_evens([1,2,3,4]) + 2 + >>> + """ + cnt = 0 + if not type(lst) is list: + return 0 + else: + for x in lst: + if not type(x) is int: + pass + else: + if x % 2 == 0: + cnt += 1 + return cnt + +if __name__ == "__main__": + print(count_evens([2,2,8,4])) \ No newline at end of file diff --git a/driver_dispatch.py b/driver_dispatch.py new file mode 100644 index 0000000..89886cf --- /dev/null +++ b/driver_dispatch.py @@ -0,0 +1,72 @@ +# $Id: play03.py,v 1.3 2017/02/04 20:32:31 larry Exp larry $ + +# Dictionary | key = int of driver ID | val = list of dispatcher ID +dis_dr_id = {'44': None,'15': [5], '13': [5], '2': [5], '26': [5], '39': [5], + '42': [5], '29': [5], '17': [5], '41': [5], '22': [5], '27': [5], + '24': [5], '18': [5], '21': [5], '36': [5], '14': [5], '19': [5], + '4': [5], '9': [5], '37': [5], '32': [5], '3': [5], '46': None, + '34': [5], '35': [5], '40': [5], '7': [5], '8': [5], '5': [5], + '33': [5], '45': None, '12': [5], '6': [5], '38': [5], '10': [5], + '31': [5], '1': [3, 5], '23': [5], '25': [5], '30': [5], '20': [5], + '43': None, '16': [5], '28': [5], '11': [5]} + +def find_dispatcher (dr_id, co_id): + """ + Find dispatcher function + - Arguments are driver ID & co-driver ID + - Returns dispatcher common to both or None if not found + Example ... + dis_dr_id = {"1":[5],"2":[5]} + find_dispatcher(1,2) returns [5] + """ + + # Highest possible driver number + top_num = 100 + tst_lst = [x for x in range(1, top_num + 1)] + + # Various error checks + # Does database exist + if not 'dis_dr_id' in globals(): + return "Database does not exist!" + # Test if driver & co-driver ID are integers + elif not type(dr_id) is int or not type(co_id) is int: + return "Driver ID & co-driver ID must be integers!" + # Test values of driver & co-driver IDs + elif not dr_id in tst_lst or not co_id in tst_lst: + return "Driver ID & co-driver ID must be between 1 and " + str(top_num) + # Check if driver in database + elif not str(dr_id) in dis_dr_id: + return "Driver ID not in database." + # Check if co-driver in database + elif not str(co_id) in dis_dr_id: + return "Co-driver ID not in database." + + # Driver, list of lists + dr_lst = [] + + # Co-driver, list of lists + co_lst = [] + + # Create list of dispatchers for driver & co-driver + for x in dis_dr_id: + if x == str(dr_id) and dis_dr_id[x] != None: + dr_lst.append((dis_dr_id[x])) + if x == str(co_id) and dis_dr_id[x] != None: + co_lst.append((dis_dr_id[x])) + + # Common dispatcher list + dis_lst = [] + + for a in dr_lst: + for b in a: + for c in co_lst: + if b in c: + dis_lst.append(b) + + if len(dis_lst) > 0: + return list(set(dis_lst)) + else: + return None + +if __name__ == "__main__": + print(find_dispatcher(1, 2)) diff --git a/fizzbizz.py b/fizzbizz.py new file mode 100644 index 0000000..27e216f --- /dev/null +++ b/fizzbizz.py @@ -0,0 +1,34 @@ + + +def fizzbizz(lst): + """ + Simple error checking + Takes a list as an argument + Numbers that are divisable by 3 are replaced by FIZZ + Numbers that are divisable by 5 are replaced by BIZZ + Numbers that are divisable by 3 & 5 are replaced by FIZZBIZZ + >>> fizzbizz([x for x in range(1,16)]) + [1, 2, 'FIZZ', 4, 'BIZZ', 'FIZZ', 7, 8, 'FIZZ', 'BIZZ', 11, 'FIZZ', 13, 14, 'FIZZBIZZ'] + """ + # Test for a valid lst + if not type(lst) is list: + return None + # Replace divisable by 3 & 5 + for x in lst: + if x % 3 == 0 and x % 5 == 0: + lst[x-1] = "FIZZBIZZ" + # Replace divisable by 3 + for x in lst: + if type(x) is int: + if x % 3 == 0: + lst[x-1] = "FIZZ" + # Replace divisable by 5 + for x in lst: + if type(x) is int: + if x % 5 == 0: + lst[x-1] = "BIZZ" + + return lst + +if __name__ == "__main__": + print(fizzbizz([x for x in range(1,101)])) \ No newline at end of file diff --git a/grid_maker.py b/grid_maker.py new file mode 100644 index 0000000..6dd05ad --- /dev/null +++ b/grid_maker.py @@ -0,0 +1,51 @@ + +import sys + +class Grid_Maker: + """ + Create a user defined grid with error check + Returns a formatted string + Parameters are: + - s (side character of grid) + - t (top character of grid) + - c (corner character of grid) + - h (number of side characters) + - w (number of top characters) + - b (number of boxes) + """ + # Initialize + def __init__(self, s = '|', t = '-', c = '+', h = 5, w = 5, b = 2): + self.s = s + self.t = t + self.c = c + self.h = h + self.w = w + self.b = b + # Create grid + def draw_grid(self): + """ + Creates a user defined grid + """ + try: + if self.b == 1: + # Single box + v1 = self.c + (self.t * self.w) + self.c + "\n" + v2 = self.s + (" " * self.w) + self.s + "\n" + return v1 + (v2 * self.h) + v1[:-1] + else: + # Left corner + top + v1 = self.c + (self.t * self.w) + # Left side + middle + v2 = self.s + (" " * self.w) + # Create string representing grid + v3 = (v1 * self.b) + self.c + "\n" + for x in range(self.h): + v3 = v3 + (v2 * self.b) + self.s + "\n" + # Return string + return (v3 * self.b) + (self.b * v1) + self.c + except: + return "Please check arguments.\nThey must be 3 single characters & 3 integers." + +if __name__ == "__main__": + gm = Grid_Maker() + print(gm.draw_grid()) \ No newline at end of file diff --git a/mailroom.py b/mailroom.py new file mode 100644 index 0000000..09ba4ac --- /dev/null +++ b/mailroom.py @@ -0,0 +1,275 @@ +# $Id: play01.py,v 1.11 2017/02/12 20:27:25 larry Exp $ + +# Various import +# --------------------------------------------------------------- +import sys +import pickle +import os.path +import datetime +# --------------------------------------------------------------- + +# Create dictionary +donors = { +"Bugs Bunny":[1000, 2000, 3000], +"Elmer Fudd":[500, 1200, 1600], +"Foghorn Leghorn":[800, 1600, 2400], +"Daffy Duck":[550, 750, 2400], +"Johnny Quest":[300, 600, 900], +"Marvin Martian":[5000, 10000, 20000], +"Porky Pig":[2500, 2800, 3000]} + +# Open the pickle +try: + # Open the pickle + file_obj = open("/home/larry/UW/Play/donors", 'wb') + + # Put the donor dictionary in the pickle + pickle.dump(donors, file_obj) + + # Close the pickle + file_obj.close() + +except: + print("Could not open file, system exiting.") + sys.exit() + +# Open pickle for use, data looks like the following: name + donation amounts +# {'Bugs Bunny': [1000, 2000, 3000], etc. +donor_dict = pickle.load(open("donors", "rb")) + +class menu_play: + """ + Reads a pickle database into memory + Dynamic menu + Makes method choice based on user input + """ + + def __init__(self, msg = ["Placeholder"]): + """ + Parameter is a list of from 1 to 9 strings + """ + self.msg = msg + + def get_input(self): + """ + User selects a routine + """ + # Creates available choices list + tst = [str(x) for x in range(1, len(self.msg) + 1)] + + # First element in menu choices + v1 = tst[0] + + # Last element in menu choices + v2 = tst[-1] + + # Show menu + self.make_tui() + + # Insist on correct input & give feedback if wrong + while True: + chc = input() + if not chc in tst: + self.make_tui() + print("You must enter a number from %s to %s." % (v1, v2)) + else: + break + + # All available menu methods + my_methods = {"1" : self.m1, + "2" : self.m2, + "3" : self.m3, + "4" : self.m4, + "5" : self.m5, + "6" : self.m6, + "7" : self.m7, + "8" : self.m8, + "9" : self.m9} + + # Call menu method based on user choice + my_methods[chc]() + + def m1(self): + """ + Add donor to database, check if name exists, give feedback to user + """ + # Add donor if name is not existing in database + while True: + chc = input("Enter donor name to add: ") + if chc in donors: + print("Donor name %s already exists in database." % (chc)) + else: + break + + donors[chc] = [] + print("%s added to donor database." % (chc)) + + def m2(self): + """ + Remove donor from database + """ + # Remove donor if name exists in database + while True: + chc = input("Enter donor name to remove: ") + if not chc in donors: + print("Donor name %s does not exist in database." % (chc)) + else: + break + + del donors[chc] + print("%s removed from donor database." % (chc)) + + def m3(self): + """ + Find donor in database + """ + # Get name of donor + while True: + chc = input("Enter donor name to report on: ") + if not chc in donors: + print("Donor name %s does not exist in database." % (chc)) + else: + break + + # Donor name, number of donations, total & average donations + num = str(len(donors[chc])) + tot = sum(donors[chc]) + ave = float(sum(donors[chc]) / int(num)) + print("Name: %s ... Donations: %s ... Total: $%0.2f ... Average: $%0.2f." % (chc, num, tot, ave)) + + def m4(self): + """ + Add donation + """ + # Name of donor + while True: + chc = input("Enter donor name to record donation to: ") + if not chc in donors: + print("Donor name %s does not exist in database." % (chc)) + else: + break + + # Amount of donation + new_don = 0 + while True: + try: + new_don = abs(float(input("Enter donation amount: "))) + except ValueError: + print("Not an number!") + continue + else: + break + + # Add donation to dictionary value key + donors[chc].append(new_don) + + # Alert user + print("You have added $%.2f to %s's donation total." % (new_don, chc)) + + def m5(self): + """ + Report on selected donors + """ + for x in donors: + tot = sum(donors.get(x)) + num = len(donors.get(x)) + ave = float(tot) / num + print("Name: %s ... Donations: %s ... Total: $%0.2f ... Average: $%0.2f." % (x, num, tot, ave)) + + def m6(self): + """ + Generate thank you letter + """ + # Date and time + tm = [] + today = datetime.date.today() + tm.append(today) + tm = tm[0] + + # Name of donor + while True: + chc = input("Enter donor name to record donation to: ") + if not chc in donors: + print("Donor name %s does not exist in database." % (chc)) + else: + break + + # Donor total + tot = sum(donors.get(chc)) + + print("%s\n\nDear %s,\nThank you for your generous donation of $%0.2f.\n\nSincerely\n\nDonation committee" % (tm, chc, tot)) + + def m7(self): + """ + Ends mailroom routine + """ + print("Mailroom ending") + sys.exit() + + def m8(self): + """ + Placeholder + """ + pass + + def m9(self): + """ + Placeholder + """ + pass + + def make_tui(self): + """ + Create simple TUI + Maximum length of supplied string parameters is 50 characters. + Maximum number of categories is 9 + Example | parameter = ["Report", "Thank you", "Quit"] + +------------------------------+ + | Enter value and press RETURN | + | [1] Report | + | [2] Thank you | + | [3] Quit | + +------------------------------+ + """ + + # Check that supplied parameter is a valid list + if len(self.msg) < 1 or len(self.msg) > 9: + print("List must contain 1 to 9 strings") + sys.exit() + + # Test string parameters in list + for x in self.msg: + if not type(x) is str or len(x) < 0 or len(x) > 50: + print("List parameters must be strings between 0 & 50") + sys.exit() + + hdr = "Enter value and press RETURN" + hln = len(hdr) + + # Longest string in list + ls = 0 + for x in self.msg: + if len(x) > ls: + ls = len(x) + + # Width of TUI + if hln >= ls: + spc = hln-3 + else: + spc = ls + 1 + + # Create interface + cnt = 1 + + print("\n+" + ("-" * (spc + 5)) + "+") + print("| " + hdr + (((spc + 4) - len(hdr)) * " ") + "|") + for x in self.msg: + v1 = spc - len(x) + print("| " + "[" + str(cnt) + "] " + x + v1 * " " + "|") + cnt += 1 + print("+" + ("-" * (spc + 5)) + "+") + +if __name__ == "__main__": + lst = ["Add", "Remove", "Find", "Donation", "Report", "Thank you", "Quit"] + mail_room = menu_play(lst) + mail_room.get_input() diff --git a/maleyl/ch_proj01.py b/maleyl/ch_proj01.py new file mode 100644 index 0000000..4b217b9 --- /dev/null +++ b/maleyl/ch_proj01.py @@ -0,0 +1,513 @@ +# $Id: ch_proj01.py,v 1.9 2017/03/09 01:58:12 larry Exp $ + +# IMPORTS +from Tkinter import * +from tkFileDialog import askopenfilename +import tkMessageBox +import six +import sys +import pytest +import doctest +import csv +from buzhug import Base + +# Function to create database +def create_db(): + """ + Open csv file, cleanup data + """ + + # Keep GUI very simple + Tk().withdraw() + + # Get csv filename + try: + fn = askopenfilename(filetypes=[("csv files","*.csv")]) + if not fn: + sys.exit() + except: + sys.exit() + + lst1 = [] + lst2 =[] + + # Open csv file, convert to list + try: + csv_file = open(fn, "r") + myfile = csv.reader(csv_file) + for x in myfile: + lst1.append(x) + except: + print("Could not open csv file.") + finally: + csv_file.close() + + # Clean up data, back & forth between 2 lists + # Remove first line + lst1 = lst1[1:] + + # Upper case all data + for x in lst1: + lst2.append(map (lambda var: var.upper(), x)) + + lst1 = [] + # Remove the last 6 elements of the list + for x in lst2: + lst1.append(x[:-6]) + + # Remove ODD/EVEN from list + for x in lst1: + del x[9] + + # Remove the five couplers & all blanks + csv_data = [] + for x in lst1: + if x[1]: + csv_data.append(x[:-7] + x[17:]) + + # Create database if not existing + # Folder name is CH_FILE, object name is ch_dat + ch_dat = Base('CH_FILE') + # "open" MODE WILL NOT OVERWRITE, "override" MODE WILL + + # Creates an empty database + ch_dat.create(('SITE_NAME',str), + ('JT_NUM',str), + ('PHASE',str), + ('HUB',str), + ('PRETERM',str), + ('PORT',str), + ('SHEATH',str), + ('TOWER_TX',str), + ('HUB_TX',str), + ('HUB_MUX_NUM',str), + ('HUB_MUX_TYPE',str), + ('TWR_GROUP',str), + ('FIELD_MUX_NAME',str), + ('FIELD_MUX_TYPE',str),mode='override') + + # # Insert into database + for var in csv_data: + ch_dat.insert(var[0],var[1],var[2],var[3],var[4], + var[5],var[6],var[7],var[8],var[9], + var[10],var[11],var[12],var[13]) + +class ChannelTool(Frame): + ''' + Class for basic data input and output + ''' + + def __init__(self, parent): + ''' + Ininializes basic GUI + Calls basic methods + ''' + + # List of Washington State HUBs + self.hubs = ["ABERDEEN","ANACORTES","AVONDALE","BELLEVUE","BELLINGHAM", + "BEVERLY LANE","BONNEY LAKE","BREMERTON","BURIEN", + "BURLINGTON","CEDAR DOWNS","CENTRALIA","CLEARVIEW","DEMING", + "ELMA","ENUMCLAW","EVERETT","FEDERAL WAY","FERNDALE", + "FORT LEWIS","FREELAND","GIG HARBOR","GRAHAM","GREEN LAKE", + "ISSAQUAH","KENT VISTA","KIRKLAND","LAKE CITY EAST", + "LAKE CITY WEST","LAKE STEVENS","LAKEWOOD","LYNDEN", + "LYNNWOOD","MADISON PARK","MARYSVILLE","MONROE", + "NORTH BEND","NORTH EVERETT","OAK HARBOR","OB2 EAST DATA", + "OLYMPIA","TUMWATER","OTN A","OTN B","OTN C","OTN D", + "OTN E","OTN F","PARKLAND","PINE LAKE","POULSBO","PUYALLUP", + "QUEEN ANNE","RAYMOND","REDMOND","ROOSEVELT","SEA TAC", + "SHELTON","SILVER LAKE","SNOHOMISH","SOUTH SEATTLE", + "SPOKANE","SPOKANE EAST","SPOKANE WEST","TACOMA", + "TACOMA EAST","UNIVERSITY EAST","UNIVERSITY WEST","VASHON", + "WESTIN","WESTPORT","WOODINVILLE"] + + # GUI + Frame.__init__(self, parent) + self.parent = parent + self.initUI() + self.make_widgets() + + def initUI(self): + self.parent.title('Channel tool') + self.pack(fill=BOTH, expand=1) + + def make_widgets(self): + ''' + Creates all basic frames and widgets + ''' + + # String variables + # Site Name + self.sitename_var = StringVar() + # JT Number + self.jt_var = StringVar() + # Preterm + self.preterm_var = StringVar() + # Port + self.port_var = StringVar() + # HUB MUX number + self.hubmuxnum_var = StringVar() + # HUB MUX Type + self.hubmuxtype_var = StringVar() + # Field MUX Name + self.fieldmuxname_var = StringVar() + # Field MUX Type + self.fieldmuxtype_var = StringVar() + # Tower Group + self.towergroup_var = StringVar() + # HUB TX + self.hubtx_var = StringVar() + # Tower TX + self.twrtx_var = StringVar() + + # Frames + # Main Frame (Holds all other frames) + self.frm_00 = Frame(self) + self.frm_00.config(relief=RIDGE,bd=2) + self.frm_00.pack(expand=1,fill=BOTH,side=TOP,anchor=N) + + # Menu Frame (Top of main frame) + self.frm_mnu = Frame(self.frm_00) + self.frm_mnu.pack(side=TOP,anchor=W) + + # View Data Label Frame + self.frm_modify_label = Frame(self.frm_00) + self.frm_modify_label.pack(side=TOP,anchor=N,fill=BOTH) + + # Modify Frame + self.frm_modify = Frame(self.frm_00) + self.frm_modify.pack(expand=0,fill=BOTH,side=TOP,anchor=N,padx=1,pady=1) + + # Modify Right Frame + self.frm_modify_right = Frame(self.frm_modify) + self.frm_modify_right.pack(expand=1,fill=BOTH,side=RIGHT,anchor=N,padx=2,pady=1) + + # Modify Left Frame + self.frm_modify_left = Frame(self.frm_modify) + self.frm_modify_left.pack(expand=0,fill=BOTH,side=LEFT,anchor=N,padx=1,pady=0) + + # View Data Label Frame + self.frm_view_label = Frame(self.frm_00) + self.frm_view_label.pack(side=TOP,anchor=N,fill=BOTH) + + # Entry Frame Parent + self.frm_entry = Frame(self.frm_modify_right) + self.frm_entry.pack(expand=1,fill=BOTH,side=TOP,anchor=N,padx=1,pady=1) + + # Entry Frame A + self.frm_entry_a = Frame(self.frm_entry) + self.frm_entry_a.pack(expand=1,fill=BOTH,side=TOP,anchor=N) + + # Entry Frame B + self.frm_entry_b = Frame(self.frm_entry) + self.frm_entry_b.pack(expand=1,fill=BOTH,side=TOP,anchor=N) + + # Entry Frame C + self.frm_entry_c = Frame(self.frm_entry) + self.frm_entry_c.pack(expand=1,fill=BOTH,side=TOP,anchor=N) + + # Category Labels Frame + self.frm_cat = Frame(self.frm_00,bg='light grey') + self.frm_cat.pack(side=TOP,anchor=NW,fill=X,expand=0) + + # View Frame + self.frm_view = Frame(self.frm_00,bg='light grey') + self.frm_view.pack(side=TOP,fill=BOTH,expand=1,anchor=N) + + # View Right Frame + self.frm_view_right = Frame(self.frm_view,bg='light grey') + self.frm_view_right.pack(side=LEFT,fill=BOTH,expand=1,anchor=NW) + + # Report Frame + self.frm_report = Frame(self.frm_00) + self.frm_report.pack(side=TOP,fill=BOTH,expand=1,anchor=N) + + # Button Frame + self.frm_run = Frame(self.frm_00) + self.frm_run.pack(side=BOTTOM,fill=X,anchor=S) + + # File Menu + self.mnu_file_btn = Menubutton(self.frm_mnu,text='File',underline=0,bg='grey') + self.mnu_file_btn.pack(side=LEFT) + file = Menu(self.mnu_file_btn, tearoff=0) + self.mnu_file_btn.config(menu=file) + + # Menu Exit (File) + file.add_command(label='Quit...',underline=0,command=sys.exit) + + # Tools Menu + self.mnu_edit_btn = Menubutton(self.frm_mnu,text='Tools',underline=0,bg='grey') + self.mnu_edit_btn.pack(side=LEFT) + file = Menu(self.mnu_edit_btn, tearoff=0) + self.mnu_edit_btn.config(menu=file) + + # New Record (Tools) + file.add_command(label='New site...',underline=0) + + # Modify (Tools) + file.add_command(label='Modify site...',underline=0) + + # Remove (Tools) + file.add_command(label='Remove site...',underline=0) + + # Search jobs (Tools) + file.add_command(label='Search site...',underline=0) + + # View Menu + self.mnu_view_btn = Menubutton(self.frm_mnu,text='View',underline=0,bg='grey') + self.mnu_view_btn.pack(side=LEFT) + file = Menu(self.mnu_view_btn, tearoff=0) + self.mnu_view_btn.config(menu=file) + + # Sort (View) + file.add_command(label='Sort...',underline=0) + + # Menu Help + self.mnu_help_btn = Menubutton(self.frm_mnu,text='Help',underline=0,bg='grey') + self.mnu_help_btn.pack(side=LEFT) + file = Menu(self.mnu_help_btn, tearoff=0) + self.mnu_help_btn.config(menu=file) + + # About + file.add_command(label='About...',underline=0) + + # Help + file.add_command(label='Help...',underline=0) + + # Filler Button (Menu) + dummy = Menubutton(self.frm_mnu,text=' '*900,bg='grey',state=DISABLED) + dummy.pack(side=LEFT,fill=X) + + # Widgets + + # Simple Line + Frame(self.frm_modify_label,bg='BLACK',relief=GROOVE,bd=2,height=2).pack(fill=X,expand=0,pady=0,side=TOP,anchor=NW) + + # Modify Label + Label(self.frm_modify_label,text='--- MODIFY OR ADD DATA ---',fg='blue').pack(side=TOP) + + # Simple Line + Frame(self.frm_view_label,bg='BLACK',relief=GROOVE,bd=2,height=2).pack(fill=X,expand=0,pady=0,side=TOP,anchor=NW) + + # View Data Label + Label(self.frm_view_label,text='--- VIEW DATA ---',fg='blue').pack() + + # Category Labels + lbl = 'HUB NAME\t\t JT #\t HUB MX\t FIELD MX\t\t\t\t\tTWR TX\tHUB TX\t SITE NAME' + self.txt_desc = Text(self.frm_cat,height=1,wrap=NONE) + self.txt_desc.pack(pady=2,anchor=W,fill=X,expand=1) + self.txt_desc.insert(END, lbl) + self.txt_desc.config(state='disabled',font='Arial 9',relief=FLAT,bg='light grey') + + # Scroll Bar (Top Left) + self.sb_sites = Scrollbar(self.frm_view_right) + self.sb_sites.pack(side=RIGHT,padx=1,pady=6,fill=Y) + + # Text Widget (Top Left) + self.txt_sites = Text(self.frm_view_right,height=10,width=100,wrap=NONE) + self.txt_sites.config(state='normal',yscrollcommand=self.sb_sites.set) + self.txt_sites.pack(pady=2,fill=BOTH,expand=1,anchor=N) + self.sb_sites.config(command=self.txt_sites.yview) + + # Label + Label(self.frm_modify_left,text='LIST OF HUBS').pack(side=TOP) + + # Scroll Bar + self.hub_scrollbar = Scrollbar(self.frm_modify_left) + self.hub_scrollbar.pack(side=RIGHT,padx=1,pady=1,fill=Y) + + # Hub Name + self.lst_hub = Listbox(self.frm_modify_left,height=6,width=14,selectmode=SINGLE) + self.lst_hub.config(state=DISABLED,yscrollcommand=self.hub_scrollbar.set) + self.lst_hub.pack(padx=1,pady=1,fill=BOTH,expand=1,anchor=N) + self.hub_scrollbar.config(command=self.lst_hub.yview) + + # Site Name + Label(self.frm_entry_a,text='Site Name: ').pack(anchor=NW,padx=2,pady=4,side=LEFT) + self.ent_name=Entry(self.frm_entry_a,width=22,textvariable=self.sitename_var) + self.ent_name.config(state=DISABLED) + self.ent_name.pack(anchor=NW,padx=2,pady=4,side=LEFT,expand=1,fill=X) + + # JT Number + Label(self.frm_entry_a,text=' JT Number:').pack(anchor=NW,padx=2,pady=4,side=LEFT) + self.ent_jt=Entry(self.frm_entry_a,width=6,textvariable=self.jt_var) + self.ent_jt.config(state=DISABLED) + self.ent_jt.pack(anchor=NW,padx=2,pady=4,side=LEFT) + + # Preterm + Label(self.frm_entry_a,text=' Preterm:').pack(anchor=NW,padx=2,pady=4,side=LEFT) + self.ent_preterm=Entry(self.frm_entry_a,width=10,textvariable=self.preterm_var) + self.ent_preterm.config(state=DISABLED) + self.ent_preterm.pack(anchor=NW,padx=2,pady=4,side=LEFT) + + # Port + Label(self.frm_entry_a,text=' Port:').pack(anchor=NW,padx=2,pady=4,side=LEFT) + self.ent_port=Entry(self.frm_entry_a,width=5,textvariable=self.port_var) + self.ent_port.config(state=DISABLED) + self.ent_port.pack(anchor=NW,padx=2,pady=4,side=LEFT) + + # HUB MUX Number + Label(self.frm_entry_a,text='HUB MUX #:').pack(anchor=NW,padx=2,pady=6,side=LEFT) + self.ent_hubmuxnum=Entry(self.frm_entry_a,width=6,textvariable=self.hubmuxnum_var) + self.ent_hubmuxnum.config(state=DISABLED) + self.ent_hubmuxnum.pack(anchor=NW,padx=2,pady=4,side=LEFT) + + # HUB MUX Type + Label(self.frm_entry_a,text=' HUB MUX Type:').pack(anchor=NW,padx=2,pady=6,side=LEFT) + self.hubmuxtype_var.set('40') + self.opt_mnu_hubmuxtype = OptionMenu(self.frm_entry_a,self.hubmuxtype_var, '40','40X') + self.opt_mnu_hubmuxtype.config(width=6,state=DISABLED) + self.opt_mnu_hubmuxtype.pack(anchor=NW,padx=1,pady=4,side=LEFT) + + # Field MUX Name + Label(self.frm_entry_b,text='MUX Name:').pack(anchor=NW,padx=2,pady=6,side=LEFT) + self.ent_fieldmuxname=Entry(self.frm_entry_b,width=43,textvariable=self.fieldmuxname_var) + self.ent_fieldmuxname.config(state=DISABLED) + self.ent_fieldmuxname.pack(anchor=NW,padx=2,pady=4,side=LEFT,expand=0,fill=X) + + # Field MUX Type + Label(self.frm_entry_b,text=' Field MUX Type:').pack(anchor=NW,padx=2,pady=6,side=LEFT) + self.fieldmuxtype_var.set('TBD') + self.opt_mnu_fieldmuxtype = OptionMenu(self.frm_entry_b,self.fieldmuxtype_var, "One","Two","Three") + self.opt_mnu_fieldmuxtype.config(width=8,state=DISABLED) + self.opt_mnu_fieldmuxtype.pack(anchor=NW,padx=2,pady=4,side=LEFT) + + # Tower Group + Label(self.frm_entry_b,text=' Tower Group:').pack(anchor=NW,padx=2,pady=6,side=LEFT) + self.towergroup_var.set('0') + self.opt_mnu_twrgroup = OptionMenu(self.frm_entry_b,self.towergroup_var, '0','1','2','3','421','422','423') + self.opt_mnu_twrgroup.config(width=8,state=DISABLED) + self.opt_mnu_twrgroup.pack(anchor=NW,padx=2,pady=4,side=LEFT) + + # HUB TX + Label(self.frm_entry_b,text=' HUB TX:').pack(anchor=NW,padx=2,pady=4,side=LEFT) + self.ent_hubtx=Entry(self.frm_entry_b,width=9,textvariable=self.hubtx_var) + self.ent_hubtx.config(state=DISABLED) + self.ent_hubtx.pack(anchor=NW,padx=2,pady=4,side=LEFT) + + # TWR TX + Label(self.frm_entry_b,text=' Tower TX:').pack(anchor=NW,padx=2,pady=4,side=LEFT) + self.ent_twrtx=Entry(self.frm_entry_b,width=10,textvariable=self.twrtx_var) + self.ent_twrtx.config(state=DISABLED) + self.ent_twrtx.pack(anchor=NW,padx=2,pady=4,side=LEFT) + + # Apply + self.btn_go = Button(self.frm_entry_c,text='Apply') + self.btn_go.pack(side=RIGHT,anchor=W,pady=1,padx=2) + self.btn_go.config(state=DISABLED) + Label(self.frm_entry_c,text='Create or modify data, then press apply. ').pack(anchor=W,side=RIGHT) + + # Simple Line + Frame(self.frm_report,bg='BLACK',relief=GROOVE,bd=2,height=2).pack(fill=X,expand=0,pady=1,side=TOP,anchor=NW) + + # Report Label (Report Frame) + Label(self.frm_report,text='--- CHANNEL REPORT ---',fg='blue').pack() + + # Scroll Bar (Report Frame) + self.report_scrollbar = Scrollbar(self.frm_report) + self.report_scrollbar.pack(side=RIGHT,padx=1,pady=2,fill=Y) + + # Report View (Report Frame) + self.txt_report = Text(self.frm_report,height=10,width=125) + self.txt_report.config(state='normal',yscrollcommand=self.report_scrollbar.set) + self.txt_report.pack(padx=1,pady=1,fill=BOTH,expand=1,anchor=N) + self.report_scrollbar.config(command=self.txt_report.yview) + + # Report (Report Frame) + self.btn_report = Button(self.frm_run,text='Run') + self.btn_report.pack(side=RIGHT,anchor=SE,padx=5,pady=1) + + # Report Label (Run Frame) + ch_label='Create channel report.' + Label(self.frm_run,text=ch_label).pack(side=RIGHT,anchor=E) + + +class Hub: + """ + Primary or secondary HUB. Attributes are ... + - HUB name (from list, eg. "WABU", "WAGL", etc.) + - HUB type (eg. "PRI", "SEC") + - List of preterm panels (objects) + - List of equipment (eg. "JUNIPER", "4200") + - List of MUXes (objects) + """ + + def __init__(self, hub_name, hub_type, hub_equip): + """ + Initialize HUB variables with some error checking + """ + + # HUB name with error checking + if not hub_name in self.hub_lst: + raise ParamException("Hub name must be a valid HUB.") + else: + self._hub_name = hub_name + + # HUB type with error checking + if not hub_type in self.hub_type_lst: + raise ParamException("Hub type must be PRI or SEC.") + else: + self._hub_type = hub_type + + # Set up decorators + @property + def hub_name(self): + """ + Returns HUB name + """ + return self._hub_name + + @hub_name.setter + def hub_name(self, var): + """ + Set HUB name with error checking + """ + if var in self.hub_lst: + self._hub_name = var + + @property + def hub_type(self): + """ + Returns HUB type + """ + return self._hub_type + + @hub_type.setter + def hub_type(self, var): + """ + Set HUB type with error checking + """ + if var in self.hub_type_lst: + self._hub_type = var + + + def add_preterms(self, pre_name): + self.preterms.append(PreTerm(self.pre_name)) + + +class PreTerm: + """ + Placeholder + """ + def __init__(self, pre_name): + self.pre_name = pre_name + +def main(): + # One time use, creates database from csv file record + # create_db() + + # Call dialog + root = Tk() + # Get screen width + wid = root.winfo_screenwidth() + # Get screen height + hgt = root.winfo_screenheight() + # Dialog is full screen + root.geometry("%dx%d+0+0" % (wid, hgt)) + # Create instance and run + ch_app = ChannelTool(root) + root.mainloop() + +# --------------------------------------------------------------- +if __name__ == '__main__': + main() diff --git a/maleyl/driver_dispatch.py b/maleyl/driver_dispatch.py new file mode 100644 index 0000000..89886cf --- /dev/null +++ b/maleyl/driver_dispatch.py @@ -0,0 +1,72 @@ +# $Id: play03.py,v 1.3 2017/02/04 20:32:31 larry Exp larry $ + +# Dictionary | key = int of driver ID | val = list of dispatcher ID +dis_dr_id = {'44': None,'15': [5], '13': [5], '2': [5], '26': [5], '39': [5], + '42': [5], '29': [5], '17': [5], '41': [5], '22': [5], '27': [5], + '24': [5], '18': [5], '21': [5], '36': [5], '14': [5], '19': [5], + '4': [5], '9': [5], '37': [5], '32': [5], '3': [5], '46': None, + '34': [5], '35': [5], '40': [5], '7': [5], '8': [5], '5': [5], + '33': [5], '45': None, '12': [5], '6': [5], '38': [5], '10': [5], + '31': [5], '1': [3, 5], '23': [5], '25': [5], '30': [5], '20': [5], + '43': None, '16': [5], '28': [5], '11': [5]} + +def find_dispatcher (dr_id, co_id): + """ + Find dispatcher function + - Arguments are driver ID & co-driver ID + - Returns dispatcher common to both or None if not found + Example ... + dis_dr_id = {"1":[5],"2":[5]} + find_dispatcher(1,2) returns [5] + """ + + # Highest possible driver number + top_num = 100 + tst_lst = [x for x in range(1, top_num + 1)] + + # Various error checks + # Does database exist + if not 'dis_dr_id' in globals(): + return "Database does not exist!" + # Test if driver & co-driver ID are integers + elif not type(dr_id) is int or not type(co_id) is int: + return "Driver ID & co-driver ID must be integers!" + # Test values of driver & co-driver IDs + elif not dr_id in tst_lst or not co_id in tst_lst: + return "Driver ID & co-driver ID must be between 1 and " + str(top_num) + # Check if driver in database + elif not str(dr_id) in dis_dr_id: + return "Driver ID not in database." + # Check if co-driver in database + elif not str(co_id) in dis_dr_id: + return "Co-driver ID not in database." + + # Driver, list of lists + dr_lst = [] + + # Co-driver, list of lists + co_lst = [] + + # Create list of dispatchers for driver & co-driver + for x in dis_dr_id: + if x == str(dr_id) and dis_dr_id[x] != None: + dr_lst.append((dis_dr_id[x])) + if x == str(co_id) and dis_dr_id[x] != None: + co_lst.append((dis_dr_id[x])) + + # Common dispatcher list + dis_lst = [] + + for a in dr_lst: + for b in a: + for c in co_lst: + if b in c: + dis_lst.append(b) + + if len(dis_lst) > 0: + return list(set(dis_lst)) + else: + return None + +if __name__ == "__main__": + print(find_dispatcher(1, 2)) diff --git a/maleyl/mailroom.py b/maleyl/mailroom.py new file mode 100644 index 0000000..06852b5 --- /dev/null +++ b/maleyl/mailroom.py @@ -0,0 +1,275 @@ +# $Id: play01.py,v 1.11 2017/02/12 20:27:25 larry Exp $ + +# Various imports +# --------------------------------------------------------------- +import sys +import pickle +import os.path +import datetime +# --------------------------------------------------------------- + +# Create dictionary +donors = { +"Bugs Bunny":[1000, 2000, 3000], +"Elmer Fudd":[500, 1200, 1600], +"Foghorn Leghorn":[800, 1600, 2400], +"Daffy Duck":[550, 750, 2400], +"Johnny Quest":[300, 600, 900], +"Marvin Martian":[5000, 10000, 20000], +"Porky Pig":[2500, 2800, 3000]} + +# Open the pickle +try: + # Open the pickle + file_obj = open("/home/larry/UW/Play/donors", 'wb') + + # Put the donor dictionary in the pickle + pickle.dump(donors, file_obj) + + # Close the pickle + file_obj.close() + +except: + print("Could not open file, system exiting.") + sys.exit() + +# Open pickle for use, data looks like the following: name + donation amounts +# {'Bugs Bunny': [1000, 2000, 3000], etc. +donor_dict = pickle.load(open("donors", "rb")) + +class menu_play: + """ + Reads a pickle database into memory + Dynamic menu + Makes method choice based on user input + """ + + def __init__(self, msg = ["Placeholder"]): + """ + Parameter is a list of from 1 to 9 strings + """ + self.msg = msg + + def get_input(self): + """ + User can select a routine + """ + # Creates available choices list + tst = [str(x) for x in range(1, len(self.msg) + 1)] + + # First element in menu choices + v1 = tst[0] + + # Last element in menu choices + v2 = tst[-1] + + # Show menu + self.make_tui() + + # Insist on correct input & give feedback if wrong + while True: + chc = input() + if not chc in tst: + self.make_tui() + print("You must enter a number from %s to %s." % (v1, v2)) + else: + break + + # All available menu methods + my_methods = {"1" : self.m1, + "2" : self.m2, + "3" : self.m3, + "4" : self.m4, + "5" : self.m5, + "6" : self.m6, + "7" : self.m7, + "8" : self.m8, + "9" : self.m9} + + # Call menu method based on user choice + my_methods[chc]() + + def m1(self): + """ + Add donor to database, check if name exists, give feedback to user + """ + # Add donor if name is not existing in database + while True: + chc = input("Enter donor name to add: ") + if chc in donors: + print("Donor name %s already exists in database." % (chc)) + else: + break + + donors[chc] = [] + print("%s added to donor database." % (chc)) + + def m2(self): + """ + Remove donor from database + """ + # Remove donor if name exists in database + while True: + chc = input("Enter donor name to remove: ") + if not chc in donors: + print("Donor name %s does not exist in database." % (chc)) + else: + break + + del donors[chc] + print("%s removed from donor database." % (chc)) + + def m3(self): + """ + Find donor in database + """ + # Get name of donor + while True: + chc = input("Enter donor name to report on: ") + if not chc in donors: + print("Donor name %s does not exist in database." % (chc)) + else: + break + + # Donor name, number of donations, total & average donations + num = str(len(donors[chc])) + tot = sum(donors[chc]) + ave = float(sum(donors[chc]) / int(num)) + print("Name: %s ... Donations: %s ... Total: $%0.2f ... Average: $%0.2f." % (chc, num, tot, ave)) + + def m4(self): + """ + Add donation + """ + # Name of donor + while True: + chc = input("Enter donor name to record donation to: ") + if not chc in donors: + print("Donor name %s does not exist in database." % (chc)) + else: + break + + # Amount of donation + new_don = 0 + while True: + try: + new_don = abs(float(input("Enter donation amount: "))) + except ValueError: + print("Not an number!") + continue + else: + break + + # Add donation to dictionary value key + donors[chc].append(new_don) + + # Alert user + print("You have added $%.2f to %s's donation total." % (new_don, chc)) + + def m5(self): + """ + Report on selected donors + """ + for x in donors: + tot = sum(donors.get(x)) + num = len(donors.get(x)) + ave = float(tot) / num + print("Name: %s ... Donations: %s ... Total: $%0.2f ... Average: $%0.2f." % (x, num, tot, ave)) + + def m6(self): + """ + Generate thank you letter + """ + # Date and time + tm = [] + today = datetime.date.today() + tm.append(today) + tm = tm[0] + + # Name of donor + while True: + chc = input("Enter donor name to record donation to: ") + if not chc in donors: + print("Donor name %s does not exist in database." % (chc)) + else: + break + + # Donor total + tot = sum(donors.get(chc)) + + print("%s\n\nDear %s,\nThank you for your generous donation of $%0.2f.\n\nSincerely\n\nDonation committee" % (tm, chc, tot)) + + def m7(self): + """ + Ends mailroom routine + """ + print("Mailroom ending") + sys.exit() + + def m8(self): + """ + Placeholder + """ + pass + + def m9(self): + """ + Placeholder + """ + pass + + def make_tui(self): + """ + Create simple TUI + Maximum length of supplied string parameters is 50 characters. + Maximum number of categories is 9 + Example | parameter = ["Report", "Thank you", "Quit"] + +------------------------------+ + | Enter value and press RETURN | + | [1] Report | + | [2] Thank you | + | [3] Quit | + +------------------------------+ + """ + + # Check that supplied parameter is a valid list + if len(self.msg) < 1 or len(self.msg) > 9: + print("List must contain 1 to 9 strings") + sys.exit() + + # Test string parameters in list + for x in self.msg: + if not type(x) is str or len(x) < 0 or len(x) > 50: + print("List parameters must be strings between 0 & 50") + sys.exit() + + hdr = "Enter value and press RETURN" + hln = len(hdr) + + # Longest string in list + ls = 0 + for x in self.msg: + if len(x) > ls: + ls = len(x) + + # Width of TUI + if hln >= ls: + spc = hln-3 + else: + spc = ls + 1 + + # Create interface + cnt = 1 + + print("\n+" + ("-" * (spc + 5)) + "+") + print("| " + hdr + (((spc + 4) - len(hdr)) * " ") + "|") + for x in self.msg: + v1 = spc - len(x) + print("| " + "[" + str(cnt) + "] " + x + v1 * " " + "|") + cnt += 1 + print("+" + ("-" * (spc + 5)) + "+") + +if __name__ == "__main__": + lst = ["Add", "Remove", "Find", "Donation", "Report", "Thank you", "Quit"] + mail_room = menu_play(lst) + mail_room.get_input() \ No newline at end of file diff --git a/string_match.py b/string_match.py new file mode 100644 index 0000000..921bfe2 --- /dev/null +++ b/string_match.py @@ -0,0 +1,33 @@ + +import sys + +def string_match(var1, var2): + ''' + Count the number of matching 2 character sequences in 2 passed in strings + Example: string_match("aabb", "bbaa") returns 2 [the "aa" & the "bb"] + >>> string_match("aabb", "ccbbaa") + 2 + ''' + ans = 0 + # Make sure both arguments are strings & @ least 2 characters long + if not type(var1) == str or not \ + type(var2) == str or not \ + len(var1) > 1 or not \ + len(var2) > 1: + print('Both arguments must be a string, please try again.') + sys.exit() + else: + cnt = 0 + for x in var1: + if cnt == len(var1) - 1: + break + tst = x + var1[cnt + 1] + cnt += 1 + if var2.find(tst) != -1: + ans += 1 + return ans + +if __name__ == "__main__": + var1 = 'aabbcc' + var2 = 'zzbbddaaccab' + print(string_match(var1, var2))