Created
July 11, 2014 20:37
-
-
Save 1328/5032be130167d1530f32 to your computer and use it in GitHub Desktop.
comments 7-11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import sqlite3 | |
| from collections import namedtuple | |
| EMP = namedtuple('EMP', ['first_name','last_name','badge','hours']) | |
| def yes_no(query): | |
| ''' | |
| this is a simple func to as a y/n question and get back a valid y/n | |
| response | |
| this is the first of a few different ways to solve this same problem | |
| ''' | |
| check = {'y':'y','yes':'y','n':'n','no':'n'} | |
| while True: | |
| q = input(query).lower() | |
| if q in check: | |
| return check[q] | |
| print('please respond y/n') | |
| def get_valid(query, checks, transform = None): | |
| '''takes a query, runs checks, and returns a transform(input) if all | |
| funcs in checks == False | |
| note you can do the same thing with classes maybe more easily, but I will | |
| let you work up to the object oriented programing version | |
| also it is worth noting that this tends to be more trouble than it is worth | |
| because the checks and transform all get so wonkie | |
| ''' | |
| if transform is None: | |
| transfor = lambda x:x | |
| while True: | |
| q = input(query) | |
| if any(c(q) for c in checks): | |
| print('invalid entry') | |
| continue | |
| return transform(q) | |
| def yes_no_wrapper(query): | |
| '''this is just yes_no but by using a wrapper around get_valid | |
| see how complex something so simple looks? | |
| one way to fix this is to have separate validation functions | |
| ''' | |
| return get_valid(query, | |
| [lambda x:x.lower() not in ['y','yes','no','n']], | |
| lambda x: {'y':'y','yes':'y','n':'n','no':'n'}[x.lower()], | |
| ) | |
| def other_get_valid(query, func): | |
| ''' | |
| ok, maybe the others are busts. The first is too specific | |
| The second too complex | |
| how about we meet in the middle and just have a get_valid that takes in a | |
| query and a function to validate | |
| ''' | |
| while True: | |
| q = func(input(query)) | |
| if q is not None: | |
| return q | |
| def validate_name(name): | |
| ''' | |
| validate names | |
| returns None for bad ones | |
| prints a message maybe | |
| returns name.title() for good names | |
| ''' | |
| if ' ' in name: | |
| print('no spaces in names!') | |
| return None | |
| if any(l.isdigit() for l in name): | |
| print('no digits in names!') | |
| return None | |
| return name.title() | |
| def validate_number(num): | |
| if not num.isdigit(): | |
| return None | |
| return int(num) | |
| def get_employee(): | |
| '''lets break out get_employee into its own func | |
| it will make sense when you see the control flow later | |
| plus a lot is going on here with validations | |
| ''' | |
| print("******** Add New Employee ********\n") | |
| # lets use the new get_valid to force a good input | |
| first_name = get_valid('Enter Firstname:', | |
| [lambda x: any(i.isdigit() for i in x), | |
| lambda x: ' ' in x, | |
| ], | |
| lambda x:x.title() | |
| ) | |
| # hmm, a bit complex for the unitiated. Maybe this is easier | |
| last_name = other_get_valid("Enter Lastname: ", validate_name) | |
| # complex | |
| badge = get_valid("Enter Badge Number (unique): ", | |
| [lambda x:not x.isdigit()], | |
| lambda x:int(x)) | |
| # simple | |
| hours = other_get_valid("Please enter Number of hours staff member works: ", | |
| validate_number) | |
| print("\n") | |
| # return a new EMP record | |
| return (EMP(first_name, last_name, badge, hours)) | |
| def confirm_employee(e): | |
| '''not sure if this merits its own function, or just an expanded template | |
| passed to yes_no function | |
| ''' | |
| print("---- Are these details correct? ---- \n") | |
| print("Employee name = {0} {1}\n Badge Number = {2}\n Hours Worked = {3}\n".format | |
| (e.first_name, e.last_name, e.badge, e.hours)) | |
| confirm = yes_no("Press 'y' to confirm or 'n' to cancel : ") | |
| return confirm == 'y' | |
| def insert_employee(c, employee): | |
| ''' | |
| this maybe gets its own function since there is lots of error handling to | |
| do''' | |
| # break up sql long line | |
| sql =''' | |
| INSERT INTO staff ("First Name", "last name", Badge, hours) VALUES (?,?,?,?) | |
| ''' | |
| # wrap in try/except | |
| try: | |
| # check out how cool named tuples are | |
| c.execute(sql, employee) | |
| print("\n") | |
| print("New Employee {0} {1} added successfully\n".format( | |
| employee.first_name, employee.last_name)) | |
| return True | |
| except sqlite3.IntegrityError as e: | |
| # catch the unique execption | |
| print('could not insert because badge {} already in db'.format( | |
| employee.badge)) | |
| return False | |
| except Exception as e: | |
| # something else happens then raise it for debugging | |
| print('\n') | |
| print('failed on {}'.format(employee)) | |
| raise e | |
| def add_employee(c, conn): | |
| '''new add employee function | |
| it merits its own function b/c you are probably going to want to do more | |
| with the program than just add an employee | |
| ''' | |
| while True: | |
| new_guy = get_employee() | |
| if confirm_employee(new_guy): | |
| insert_employee(c, new_guy) | |
| conn.commit() | |
| keep_going = yes_no_wrapper('add another?') | |
| if keep_going =='n': | |
| return | |
| def main(): | |
| conn = sqlite3.connect('clock.db') | |
| c = conn.cursor() | |
| ''' | |
| NOTE: I would confirm column names to pep8 and the variables in the | |
| program. it keeps things more simple and it might help you in the future if | |
| you want to use dict factories. | |
| ''' | |
| c.execute('''CREATE TABLE if not exists staff (ID INTEGER PRIMARY KEY AUTOINCREMENT, "First Name", "Last Name", | |
| Badge unique , Hours)''') | |
| c.execute('''CREATE TABLE if not exists times (ID PRIMARY KEY,StaffId, ClockIn INTEGER, ClockOut INTEGER, Date INTEGER, | |
| FOREIGN KEY(StaffID) REFERENCES staff(ID))''') | |
| add_employee(c, conn) | |
| conn.close() | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment