Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Students/Dave Fugelso/Session 3/list_lab.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,3 @@
fruits.pop()
print fruits
print fruitsCopy

31 changes: 31 additions & 0 deletions Students/Dave Fugelso/Session 4/Exceptions_lab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

'''
The raw_input() function can generate two exceptions: EOFError or KeyboardInterrupt on end-of-file(EOF) or canceled input.
Create a wrapper function, perhaps safe_input() that returns None rather rather than raising these exceptions, when
the user enters ^C for Keyboard Interrupt, or ^D (^Z on Windows) for End Of File.
Update your mailroom program to use exceptions (and IBAFP) to handle malformed numeric input
'''

def safe_input(prompt):
try:
input = raw_input(prompt)
except EOFError:
print "That won't work!"
return None
except KeyboardInterrupt:
print "HAHAHAHA... you're stuck forever"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point -- this may not be the best idea in production code....

But you got the basics of using Exceptions down -- that's the point.

return None
return input


if __name__ == "__main__":
trapped = True
while trapped:
trapString = safe_input("Try to get out: ")
if trapString is not None:
print "You wrote:", trapString
if trapString.upper() == 'Q':
trapped = False
else:
print "Would you like to play a game?"

92 changes: 92 additions & 0 deletions Students/Dave Fugelso/Session 4/dict_and_set_lab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
'''
Create a dictionary containing "name", "city", and "cake" for "Chris" from "Seattle" who likes "Chocolate".
Display the dictionary.

Delete the entry for "cake"
Display the dictionary.

Add an entry for "fruit" with "Mango" and display the dictionary.
Display the dictionary keys.

Display the dictionary values.

Display whether or not "cake" is a key in the dictionary (i.e. False) (now).

Display whether or not "Mango" is a value in the dictionary (i.e. True).

Using the dict constructor and zip, build a dictionary of numbers from zero to fifteen and the hexadecimal equivalent (string is fine).

Using the dictionary from item 1: Make a dictionary using the same keys but with the number of ts in each value.

Create sets s2, s3 and s4 that contain numbers from zero through twenty, divisible 2, 3 and 4.

Display the sets.

Display if s3 is a subset of s2 (False)

and if s4 is a subset of s2 (True).
Create a set with the letters in Python and add i to the set.
Create a frozenset with the letters in marathon
display the union and intersection of the two sets.

'''

if __name__ == "__main__":
d = {"name":"Chris", "city":"Seattle", "cake":"Chocolate"}
print d

d.pop('cake')
print d

d['fruit'] = 'Mango'
print d

print d.values()

print d.has_key('cake')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can also do:
print cake in d

a touch simpler

print 'Mango' in d.values()

nums = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,14, 15)
hexes = ('0x0', '0x1', '0x2', '0x3', '0x4','0x5', '0x6', '0x7', '0x8', '0x9', '0xa', '0xb', '0xc', '0xd', '0xe', '0xf')
hexdict = dict (zip(nums, hexes))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you got the key point. but python has a built-in hex() function that will create a hex strings from a value for you.

print hexdict

for key in d:
d[key] = d[key].count('t')
print d

#Create sets s2, s3 and s4 that contain numbers from zero through twenty, divisible 2, 3 and 4.
s2 = set()
s3 = set()
s4 = set()
for i in range (0,21):
if i % 2 == 0:
s2.add(i)
if i % 3 == 0:
s3.add(i)
if i % 4 == 0:
s4.add(i)
print s2
print s3
print s4

#Display if s3 is a subset of s2 (False)
print s3.issubset(s2)

#and if s4 is a subset of s2 (True).
print s4.issubset(s2)

#Create a set with the letters in Python and add i to the set.
py = set(list('python'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for the list() call here -- a string is already a sequence of characters.

py.add('i')
print py

#Create a frozenset with the letters in marathon
fs = frozenset (list('marathon'))
print fs

#display the union and intersection of the two sets.
print py.union(fs)
print py.intersection(fs)


188 changes: 188 additions & 0 deletions Students/Dave Fugelso/Session 4/mailroom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
"""

Dave Fugelso, UW Python Course (Developing on Windows so didn't make this an executable script.)

UPDATED: For Session 4.

1. Uses ValueError exception on numeric input
2. Uses sum to calculate total donations (Just a fix from last week)
3. Uses a Dict to hold donor names instead of a list. Key is donor name and value is list of donations.
4. Remove unnecessary line continuations in Donors initialization.

And,

5. Write a full set of letters to everyone to individual files on disk
6. See if you can use a dict to switch between the users selections
7. Try to use a dict and the .format() method to do the letter as one big template -- rather than building up a big string in parts.


Mail Room

You work in the mail room at a local charity. Part of your job is to write incredibly boring, repetitive emails thanking your donors for their generous gifts.
You are tired of doing this over an over again, so yo've decided to let Python help you out of a jam.

Write a small command-line script called mailroom.py. As with Task 1, This script should be executable. The script should accomplish the following goals:

It should have a data structure that holds a list of your donors and a history of the amounts they have donated. This structure should be populated at
first with at least five donors, with between 1 and 3 donations each
The script should prompt the user (you) to choose from a menu of 2 actions: 'Send a Thank You' or 'Create a Report'.
If the user (you) selects 'Send a Thank You', prompt for a Full Name.
If the user types 'list', show them a list of the donor names and re-prompt
If the user types a name not in the list, add that name to the data structure and use it.
If the user types a name in the list, use it.
Once a name has been selected, prompt for a donation amount.
Verify that the amount is in fact a number, and re-prompt if it isn't.
Once an amount has been given, add that amount to the donation history of the selected user.
Finally, use string formatting to compose an email thanking the donor for their generous donation. Print the email to the terminal and return to the original prompt.
It is fine to forget new donors once the script quits running.

If the user (you) selected 'Create a Report' Print a list of your donors, sorted by total historical donation amount.
Include Donor Name, total donated, number of donations and average donation amount as values in each row.
Using string formatting, format the output rows as nicely as possible. The end result should be tabular (values in each column should align with those above and below)
After printing this report, return to the original prompt.
At any point, the user should be able to quit their current task and return to the original prompt.
From the original prompt, the user should be able to quit the script cleanly
First, factor your script into separate functions. Each of the above tasks can be accomplished by a series of steps. Write discreet functions that accomplish individual steps and call them.

Second, use loops to control the logical flow of your program. Interactive programs are a classic use-case for the while loop.

Put the functions you write into the script at the top.

Put your main interaction into an if __name__ == '__main__' block.

Finally, use only functions and the basic Python data types you've learned about so far. There is no need to go any farther than that for this assignment.

As always, put the new file in your student directory in a session03 directory, and add it to your clone early. Make frequent commits with good, clear messages about what you are doing and why.

When you are done, push your changes and make a pull request.
"""

import operator
import datetime

#Donor list

donors = { 'Dave Fugelso': [3000, 6000, 4000],
'Barb Grecco': [5000],
'Ken Johnson': [500, 250, 50, 80],
'Jack Bell': [55, 55, 55, 55, 55],
'Alejandro Escobar': [25, 25]
}

def listDonors ():
'''
List donors.
'''
for key in donors:
print key, donors[key]

def report ():
'''
Create a report with Name, Total Donation, Number of Donation and average donation size. Print largest donor first.
'''

# go through list and calculate donor metrics
for key in donors:
print key, donors[key], sum(donors[key])

#print it out
print '\n\nDonor\t\t\t\tAmount\t\tNumber of Donations\t\tAverage Donation'
print '-----\t\t\t\t------\t\t-------------------\t\t----------------'

# Sorting a dict by sum of the values... kinda tough. Fond a great lambda func to do that on Stack Overflow, but
# in the spirit of not getting to far out from the current topic, going to create a list and use the same sort.

# iterate over the dictionary and create a list of donor, totals
#Check here later to see f we can geta list of keys without iterating.... TBD
sortlist = list()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usally see:

sortlist = []

though it does do the same thing.

for key in donors:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure:

donors. keys()

is a list of the keys.

sortlist.append ( key )

for donorName in sorted(sortlist, key=lambda individual: sum(donors[individual]), reverse=True):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

print donorName,
if len(donorName) < 15:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as you can see, formatting with tabs is a nightmare -- Id do just spaces.
and you can use string formatting to put stuff in columns with spaces.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh -- and even with the pain you've gone through, it would break on most *nix terminals -- they generally use 8 spaces per tab be default...

print '\t\t\t',
else:
print '\t\t',
print sum(donors[donorName]),
print '\t\t\t',
if len(donors[donorName]) > 0:
print len(donors[donorName]),
print '\t\t\t',
print sum(donors[donorName]) / len(donors[donorName])
else:
print '0\t\tNA'
print '\n\n\n\n'

def thankYou (fullname, donations):
'''
Send off a thank you note to a single donor.
'''
print '\n\n\n\n\t\t\t\t\t',datetime.date.today()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice job finding datetime!

print '\nOur Charity Name\nAddress\nEtc\n\n\n'
name = fullname.split()
print 'Dear '+name[0]+':\n'
if len(donations) <= 1:
print 'Thank you for your donation of ',
print donations[0]
print '.'
else:
print 'Thank you for your donations of ',
for i in range (0, len(donations)-1):
print donations[i],
print ',',
print ' and ',
print donations[len(donations)-1],
print '.'
print '\nWe look forward to serving our community blah blah blah.\n\nSincerely, \n\nOur Charity.\n\n\n\n'

def addDonor (name):
'''
Add <name> to the list of donors and get the amounts of donation.
'''
donations = []
amount = 0
while amount >= 0:
inp = raw_input ('Add amount of donation one at a time. Enter \'-1\' to finish: ')
try:
amount = int(inp)
if amount > 0:
donations.append(amount)
except ValueError:
print ('Input must be a number.')
amount = 0
donors[name] = donations




def processDonors ():
'''
Interact with administrator to manage donor list.
'''
processing = True
while processing:
action = raw_input ("Select 'Send a Thank You(S)', 'Create a report(C)', or 'Quit(Q)': ")
if action.upper() == 'S' or action.upper() == 'SEND A THANK YOU':
thankYouProcessing = True
while thankYouProcessing:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe a bit better to put the thankYouProcessing in a separate function -- if it were any more complicated or deeply nested, you'd want to keep it clean.

name = raw_input ("Enter name of donor, add a donor ('A') or ('Add'), or list all donors ('L') or ('List') or 'E' or 'End' to go to main menu: ")
if name.upper() == 'L' or name.upper() == 'LIST':
listDonors()
elif name.upper() == 'E' or name.upper() == 'END':
thankYouProcessing = False
else:
if name in donors.keys():
thankYou (name, donors[name])
else:
addDonor(name)
elif action.upper() == 'Q' or action.upper == 'QUIT':
processing = False
elif action.upper() == 'C' or action.upper == 'Create a report'.upper():
report()
else:
print 'Unrecognized input.'


if __name__ == "__main__":
processDonors ()
49 changes: 49 additions & 0 deletions Students/Dave Fugelso/Session 4/paths_lab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'''
Paths and File Processing
--------------------------

* write a program which prints the full path to all files in the current directory, one per line

* write a program which copies a file from a source, to a destination (without using shutil, or the OS copy command)
'''

import os

def myFileCopy (source, destination):
'''
Copy a file by reading the content and then writing them.
'''
try:
file_in = open(source, 'r')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

careful -- in the general case, you want tus binary mode:
file_in = open(source, 'rb')
and
file_out = open(destination, 'wb')

except FileNotFoundError:
print 'File not found'
return

try:
file_out = open(destination, 'w')
except FileExistsError:
print 'Unable to create file'
return


for line in file_in:
file_out.write(line)

file_out.close()
file_in.close()


def printFullPathInCurrentDirectory():
'''
Print all filenames in the current directory.
'''
path = os.path.dirname(os.path.abspath(__file__))
for (dirpath, dirnames, filenames) in os.walk(path):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very slick! I was only looking for os.listdir(), but this is clearly more complete!

for fname in filenames:
print os.path.join(path, fname)

if __name__ == "__main__":
printFullPathInCurrentDirectory()
myFileCopy ('t.t', 't.a')


Loading