Game Project

Due: Friday, December 2, 11:00 AM

Following on from POTD 16, your goal in this partner project is to build a bigger game! You need to use PyGame and gamebox, just as you did before.

However, this time we are letting you build whatever game you want! We will be requiring that you implement at least a basic set of features to ensure that your game is complex enough, but feel free to do more! Be careful you don't over-scope, though! You don't want to set out to build something too big that you can't finish it. If you have any questions about the scope of your game, please ask an instructor or TA.

You will be able to find gamebox and some example code at https://cs1110.cs.virginia.edu/code/gamebox. We will be adding more example code as we move through POTD 16 and the project.

You should also download and look over the gamebox API and introduction - gamebox.pdf

Partner Registration

Game Project Partner Registration - https://goo.gl/forms/mMdlkCOMQ1bkAIzo1 - NOTE: Your partner must be in the same lab as you (or both in 1111)!

Required Features

  1. User Input - Either through the keyboard or mouse, you should have appropriate and working user controls.
  2. Graphics/Images - You should use some appropriate images in your game.
  3. Start Screen - Game has a start screen with game name, student names (and IDs), and basic game instructions.

Optional Features

You must implement at least 4 of these:

  1. Animation - Use a sprite sheet to have an animated character.
  2. Enemies - Have characters that can hinder the player character from accomplishing the goal.
  3. Collectables - Add collectables (i.e. coins) to the level that can be picked up by the character with a counter that appears on the screen.
  4. Scrolling level - Make it so you can keep going off the screen! (You may need to add a background image to make this more obvious.)
  5. Timer - Have a countdown (or count up) timer for your game.
  6. Health meter - Have a health meter that changes as you hit enemies/obstacles.
  7. Music/Sound effects - Have some good sound design.
  8. Two players simultaneously - The two players MUST be able to interact directly in some way.

Game Ideas

Having trouble coming up with a game idea? Try one of these! Or make a variation of one of these!

  • Frogger - Can you get the frog across the road without getting hit by a car? Frogger on SmashingArcade
  • Pac-Man - This classic game is completely reasonable to pull off! Pac-Man on SmashingArcade
  • Keep-Away - Build a game where you character has to keep from getting "tagged" by other characters running around the level!

And many, many more! We will add more here in coming days and feel free to ask for suggestions too!

NOTE: Your game CANNOT just be an extension of example code that we provide you. You MUST show some creativity and do something on your own! The game can be based on other existing games (like the ones listed above) and you can use snipits of example code in your game, but you cannot just start from an example file and add on trivial features.

Submission

Unlike all the other submissions, this one needs to go to Collab since you may be turning in images, audio, etc. Make sure you game is called game.py and is in its own folder with all the game assets (images, audio) along with gamebox.py. Zip/archive this entire directory and submit that along with a .txt document describing what your game is, what your features are that you want us to grade, and how to play it. TAs that can't figure out how to play your game will definitely give you a low score!

ONLY ONE PARTNER SHOULD SUBMIT! PLEASE DO NOT DOUBLE SUBMIT YOUR PROJECT!!!

Partner Evals: Please fill out this evaluation form for your partner! - https://goo.gl/forms/qiUGmnJnveI8dsOK2

more ...

POTD 16 - first_game.py

Due: Tuesday, November 15, 11:00 AM

For this POTD, you should take the basic game you created in the gamebox lab and add and improve upon it. You must include at least 4 of the following features for your game. However - the exact game you make is totally up to you!

For information on getting gamebox setup, please see the lab assignment at http://cs1110.cs.virginia.edu/lab-11-gamebox-intro.html.

Your game should be different than your partner's!!! You can start from the same base code, but try to expand in different ways!

  1. The ability to jump - To do this, set the yspeed to a value like -15 when the user taps the space bar. However, you ONLY want this to work if the character is touching the ground.
  2. Other platforms - Instead of just having ground, create a list of walls (to which you can add ground). Then, you can add more walls and platforms to this list and then have a loop (for wall in walls:) where you check if your character is touching any platform.
  3. Enemy - See if you can make another character that always moves toward your character.
  4. Coins - Add coins to the level that can be picked up by the character with a counter that appears on the screen.
  5. Scrolling level - Make it so you can keep going off the screen! (You may need to add a background image to make this more obvious.)
  6. Timer - Have a countdown (or count up) timer for your game.
  7. Health meter - Have a health meter that changes as you hit enemies/obstacles.

NOTE: This game should NOT use any other files other than first_game.py and gamebox.py to simplify submission. You can load resources from the web, but we will not accept any supplemental files this time. So it is advised to limit your usage of images and definitely sounds and music. (NOTE: We have seen more issues with Macs with loading images and sounds from URLs, so we advise against doing this. Also, if you have trouble with text on your Mac, please come by office hours or just avoid using text for now.)

You will be able to find gamebox and some example code at https://cs1110.cs.virginia.edu/code/gamebox. We will be adding more example code as we move through POTD 16 and the project.

You should also download and look over the gamebox API and introduction - gamebox.pdf

Submission: Please submit one .py file named first_game.py to the POTD submission system at https://archimedes.cs.virginia.edu/cs1110/. NOTE: There is no automatic grading for this assignment! You will receive no preliminary feedback!

more ...

POTD 15 - email_finder.py

Due: Friday, November 4, 11:00 AM

Have you ever wondered how spammers get all their email addresses to send those lovely messages about foreign princes with banking troubles or the latest and greatest medication for... whatever?

We here in CS 111X want to equip you with the skills to become a spammer yourself! Well, not really, but the techniques used to farm email addresses can be really useful!

The goal of this assignment is to write a program that will scan a web page and harvest as many email addresses as possible. Many of these email address will be obfuscated in some way. It's up to you to get the computer to figure out how to recognize the obfuscation and return a good result!

Your grade will be based on how many (and what types) of email addresses you can find in the page. We will provide examples of most types of obfuscation, but not necessarily all. Some bonus points may be earned for some really tricky ones.

Here are some examples to get you started (in the form "obfuscated email" => "what your program should interpret the email as"):

  • mst3k@Virginia.EDU => mst3k@Virginia.EDU
  • thomas.jefferson@cs.virginia.edu => thomas.jefferson@cs.virginia.edu
  • mst3k at virginia.edu => mst3k@virginia.edu
  • mst3k at virginia dot edu => mst3k@virginia.edu

Tips

You can read the entire web page line by line to make it easier to search.

import urllib.request

stream = urllib.request.urlopen( "https://cs1110.cs.virginia.edu/emails.html" )

for line in stream:
    decoded = line.decode("UTF-8")
    print(decoded.strip())

Once you have a line from the web site, you have a couple different options:

  1. You can manually look for particular symbols by using the in keyword. For example, you could try if "@" in line: to see if there is an @ sign in the line you are looking at. If so, you might want to take a closer look.
  2. You can come up with regular expressions that will look for particular patterns in a line that could be an email address. You can test regular expressions against test data you provide here: http://www.regexr.com/ or https://regex101.com/

You cannot use BeautifulSoup or any other HTML parsing library for this as most of the email addresses are not within HTML tags that you can identify. So, we're going to save you some time here and just say don't try it. Further, the server will just reject your assignment.

No one method or one regular expression will get every email address. As mentioned above, we've intentionally put some extremely difficult addresses in the page just to see what you can do!

Your program must implement a particular function:

find_emails_in_website(url): This function takes as input a string representation of the URL of a website that you want to search and should return a list of the email addresses you find.

You can create as many other functions as you like, but this is the function that we will call with various different sites to see how well your program works.

We have a couple pages that you can use to test your code. These pages have a set of example emails you should be able to find (and some that you can look for but we are not requiring). Do not "hardcode" your solutions! In other words, if you write your code to look for these exact emails, then it won't work when we test it. These are just examples.

Example 1 is at: https://cs1110.cs.virginia.edu/emails.html

For the example page, you should hopefully find:

basic@virginia.edu
link-only@virginia.edu
multi-domain@cs.virginia.edu
Mr.N0body@cand3lwick-burnERS.rentals
a@b.ca
no-at-sign@virginia.edu
no-at-or-dot@virginia.edu
first.last.name@cs.virginia.edu
with-parenthesis@Virginia.EDU
added-words1@virginia.edu
added-words2@virginia.edu
may.end@with-a-period.com

Example 2 is at: https://cs1110.cs.virginia.edu/emails2.html

For the example page, you should hopefully find:

abasicemail@wfu.edu
a-link-only@unc.edu
so-many-domains@ece.berkeley.edu
SomE.CRAZY343@ea.info
w@x.yz
an-at-sign@ncsu.edu
some-other-email@gt.com
so.many.periods@why.do.this
parensarecool@duke.edu
morewords@place.net
extrawords@coolrunnings.ja
period.at@at.the.end

Submission: Submit your file email_finder.py to the POTD submission system at https://archimedes.cs.virginia.edu/cs1110/. DO NOT submit any testing files. We only want your email_finder.py file.

NOTE: Make sure to remove all print() statements from your code before submitting. We will not run any tests on any file that still has print() statements in the code!

more ...

POTD 14 - lous_list.py

Due: Friday, October 28, 11:00 AM

It's advising time! Time to start thinking about classes for the Spring! It can be tough to search through the course listings to find the classes you want. So let's write a program to help you out! The problem here that since registration for the Spring hasn't started yet, the data is kinda boring... so were are going to use data from a snapshot for registration for this semester - Fall 2016 - taken during August.

Write a library called lous_list.py that will contain two methods that will aid students in finding information about classes.

These methods will all need to read from our online custom Lou's List interface. For example, if you want to see all the courses in the CS department, can go to:

http://stardock.cs.virginia.edu/louslist/Courses/view/CS

and you'll see many lines like this:

CS;1110;002;Introduction to Programming;Ahmed Ibrahim;Lecture;3;true;false;true;false;true;1100;1150;Rice Hall 130;146;150;38.031639;-78.510811

Viewing the page "normally", it all runs together. You should view the source of the page to get a better view. (Chrome: View->Developer->View Source and Firefox: Tools->Web Developer->Page Source).

By replacing the text after the last / with any department at UVa, you can see their classes! For example, BIOL will load all Biology classes.

For each line on the page, the fields are (in order):

  • Dept ID (0)
  • Course Number (1)
  • Section (2)
  • Course Title (3)
  • Instructor (4)
  • Type of class (5)
  • Hours (6)
  • Monday (7)
  • Tuesday (8)
  • Wednesday (9)
  • Thursday (10)
  • Friday (11)
  • Start Time (12)
  • End Time (13)
  • Location (14)
  • Enrollment (15)
  • Allowable Enrollment (16)
  • Latitude (17)
  • Longitude (18)

Start and end times are expressed in the CSV as a 3- or 4-character string representing a 24-hour clock so, e.g., CS 1112 starts at 1400 and ends at 1515, for a duration of 75 minutes and CS 2150 section 105 starts at 1330 and ends at 1515 for a duration of 105 minutes.

Some sections have a listed start and end time of -1, meaning they do not have a fixed schedule.

You must do this POTD by writing these two functions:

instructors(department): Returns a sorted list containing each instructor listed in Lou's List for the given department. Do not count the same instructor twice. For example, Mark Sherriff is listed as instructor for around 19 courses for the CS department but should only appear in the resulting list once.

To test this function, you should create a separate testing file, just as you did for previous POTDs. If you invoke instructors("EAST") you should get back a list with three elements: ['Charles Laughlin', 'Jack Chen', 'Staff']. Note that the order does matter here. If you invoke instructors("URDU") you should get back a list with two element: ['Griffith Chaussee', 'Mehr Farooqi'].

class_search(dept_name, has_seats_available=True, level=None, not_before=None, not_after=None): Returns a list of lists which contains all the information for all the classes that meet the provided criteria.

By default, if you invoke class_search("CS"), the function should return a list containing all of the information from all of the CS courses in which there are seats available (Enrollment < Allowable Enrollment). If you invoke class_search("CS", False), then all classes should be displayed, regardless of enrollment. As you add the optional parameters, you can adjust the search even more, as explained below:

  • has_seats_available - If set to True, the function will check to ensure that Enrollment is not greater than or equal to Allowable Enrollment (i.e. there are seats actually available for a student to take). If set to False then it doesn't matter if there are seats available or not and current enrollment should be ignored when determining if the class should be returned or not.
  • level - Given a 4-digit level value, the function should only include classes that are at that level. For example, saying level=2000 should limit the list to only courses whose first digit is 2.
  • not_before - Tells the function to exclude all classes that start before (but not at) that time. For example, if you say not_before=1000, then the function should exclude 9:00 and 9:30 classes, but still include 10:00 classes.
  • not_after - Tells the function to exclude all classes that start after (but not at) that time. For example, if you say not_after=1400, then the function should exclude classes that start at 3:00, but not 2:00.

For example, if you invoke class_search("CS", level=1000, not_before=1600) it should return (example formatted to make it easier to read):

[
    ['CS', '1110', '106', 'Introduction to Programming', 'Mark Sherriff', 'Laboratory', '0', 'false', 'false', 'false', 'true', 'false', '1700', '1815', 'Olsson Hall 001', '45', '46', '38.032079', '-78.510755'], 
    ['CS', '1110', '107', 'Introduction to Programming', 'Mark Sherriff', 'Laboratory', '0', 'false', 'false', 'false', 'true', 'false', '1830', '1945', 'Olsson Hall 001', '44', '46', '38.032079', '-78.510755'], 
    ['CS', '1110', '108', 'Introduction to Programming', 'Mark Sherriff', 'Laboratory', '0', 'false', 'false', 'false', 'true', 'false', '2000', '2115', 'Olsson Hall 001', '27', '46', '38.032079', '-78.510755'], 
    ['CS', '1113', '', 'Introduction to Programming', 'Ahmed Ibrahim', '', '3', 'false', 'false', 'false', 'true', 'false', '1700', '1815', 'Rice Hall 130', '48', '60', '38.031639', '-78.510811'], 
    ['CS', '1113', '', 'Introduction to Programming', 'Kevin Sullivan', '', '3', 'false', 'false', 'false', 'true', 'false', '1830', '1945', 'Rice Hall 130', '43', '58', '38.031639', '-78.510811']
]

Suggested Algorithms: Unlike the previous POTD, you don't necessarily need to create a separate function to read the website data (although you can if you want). And you don't have to load all of the data into a data structure. Consider including the code to read the website at the top of each of these methods and then doing your work inside the loop in which you read each line from the website.

You cannot use Beautiful Soup or any other HTML parser - the grading system will not recognize the library and you'll get a weird header error. You must use urllib to pull down the CSV.

Submission: Please submit one .py file named lous_list.py to the POTD submission system at https://archimedes.cs.virginia.edu/cs1110/. DO NOT submit any testing files. We only want your lous_list.py file.

NOTE: Make sure to remove all print() statements from your code before submitting. We will not run any tests on any file that still has print() statements in the code!

more ...

POTD 13 - polling.py

Due: Friday, October 21, 11:00 AM

Write a program called polling.py that will read 2016 presidential election polling data from a website and do some processing on it.

The Huffington Post provides an online API for developers who want to use publicly-available polling data to do their own analyses. The API can be found at http://elections.huffingtonpost.com/pollster/api.

A set of polls for a given state can be pulled from the site via a specific URL. For instance, to get all of the data for Virginia, you would go to http://elections.huffingtonpost.com/pollster/api/charts/2016-virginia-president-trump-vs-clinton.csv. For North Carolina, you would replace virginia with north-carolina in the link above, and so on for all fifty states.

The data is in .csv format, so each column is separated by a comma. The fields are (in order):

  • Trump
  • Clinton
  • Other
  • Undecided
  • poll_id
  • pollster
  • start_date
  • end_date
  • sample_subpopulation
  • sample_size
  • mode
  • partisanship
  • partisan_affiliation

We are only going to work with the Trump percentage, Clinton percentage, and end_date fields for this assignment. So, fields 0, 1, and 7 respectively. We will only test/grade your POTD with states that have this exact format listed above (some states may lack some of the fields listed above).

UPDATE: Since this POTD has been published, an additional field was added to the Virginia data set - Johnson, right after Clinton. As we are already testing with this exact set of fields, we will continue to do so so that everyone is on equal footing. You should still use fields 0, 1, and 7 as noted above. Some other states that use the format above (currently) include Wisconsin, Maryland, Florida, and South Carolina. We will ONLY test your code with states where the data we care about is in fields 0, 1, and 7.

For this POTD, you need to write the three functions outlined below that will allow you to read and analyze the data:

1. load_state_polls(state): Given a string representation of a state like we would use above in the URL, open the URL, read the data, and return a list of lists in which each poll is a list consisting of the data items mentioned above.

You can read the entire csv line by line to make it easier to search. Example code is below. Consider how you might dynamically create that URL based upon the state that is passed into the function.

import urllib.request

stream = urllib.request.urlopen( "http://elections.huffingtonpost.com/pollster/api/charts/2016-oregon-president-trump-vs-clinton.csv" )

for line in stream:
    decoded = line.decode("UTF-8")
    print(decoded.strip())

For example, running load_state_polls('wisconsin') should return:

[['38.0', '50.0', '', '12.0', '26282', 'PPP (D-End Citizens United)', '2016-10-18', '2016-10-19', 'Likely Voters', '804', 'IVR/Online', 'Sponsor', 'Dem'], ['40.0', '47.0', '3.0', '5.0', '26274', 'Monmouth University', '2016-10-15', '2016-10-18', 'Likely Voters', '403', 'Live Phone', 'Nonpartisan', 'None'], ['39.0', '47.0', '6.0', '7.0', '26236', 'St Norbert', '2016-10-13', '2016-10-16', 'Likely Voters', '664', 'Live Phone', 'Nonpartisan', 'None'], ['44.0', '48.0', '', '8.0', '26253', 'WashPost/SurveyMonkey', '2016-10-08', '2016-10-16', 'Likely Voters', '1076', 'Internet', 'Nonpartisan', 'None'], ['42.0', '46.0', '8.0', '4.0', '26150', 'Marquette Law School', '2016-10-06', '2016-10-09', 'Likely Voters', '878', 'Live Phone', 'Nonpartisan', 'None'], ['46.0', '51.0', '4.0', '', '26045', 'UPI/CVOTER', '2016-10-02', '2016-10-09', 'Likely Voters', '349', 'Internet', 'Nonpartisan', 'None'], ['39.0', '43.0', '3.0', '11.0', '26016', 'CBS/YouGov', '2016-10-05', '2016-10-07', 'Likely Voters', '993', 'Internet', 'Nonpartisan', 'None'], ['42.0', '46.0', '', '12.0', '26137', 'Ipsos/Reuters', '2016-09-16', '2016-10-06', 'Likely Voters', '866', 'Internet', 'Nonpartisan', 'None'], ['37.0', '47.0', '7.0', '9.0', '26083', 'Loras College', '2016-10-04', '2016-10-05', 'Likely Voters', '500', 'Live Phone', 'Nonpartisan', 'None'], ['47.0', '50.0', '3.0', '', '25946', 'UPI/CVOTER', '2016-09-19', '2016-10-02', 'Likely Voters', '575', 'Internet', 'Nonpartisan', 'None'], ['42.0', '42.0', '', '16.0', '25890', 'Ipsos/Reuters', '2016-09-09', '2016-09-29', 'Likely Voters', '751', 'Internet', 'Nonpartisan', 'None'], ['46.0', '50.0', '4.0', '', '25782', 'UPI/CVOTER', '2016-09-12', '2016-09-25', 'Likely Voters', '553', 'Internet', 'Nonpartisan', 'None'], ['41.0', '41.0', '', '18.0', '25686', 'Ipsos/Reuters', '2016-09-02', '2016-09-22', 'Likely Voters', '685', 'Internet', 'Nonpartisan', 'None'], ['42.0', '44.0', '8.0', '5.0', '25601', 'Marquette Law School', '2016-09-15', '2016-09-18', 'Likely Voters', '642', 'Live Phone', 'Nonpartisan', 'None'], ['40.0', '43.0', '', '17.0', '25576', 'Ipsos/Reuters', '2016-08-26', '2016-09-15', 'Likely Voters', '695', 'Internet', 'Nonpartisan', 'None'], ['44.0', '46.0', '', '11.0', '25347', 'WashPost/SurveyMonkey', '2016-08-09', '2016-09-01', 'Registered Voters', '2687', 'Internet', 'Nonpartisan', 'None'], ['38.0', '43.0', '4.0', '8.0', '25303', 'Monmouth University', '2016-08-27', '2016-08-30', 'Likely Voters', '404', 'Live Phone', 'Nonpartisan', 'None'], ['42.0', '45.0', '7.0', '4.0', '25304', 'Marquette Law School', '2016-08-25', '2016-08-28', 'Likely Voters', '650', 'Live Phone', 'Nonpartisan', 'None'], ['41.0', '48.0', '', '12.0', '25312', 'PPP (D-NELP) ', '2016-08-26', '2016-08-27', 'Likely Voters', '1054', 'IVR/Online', 'Sponsor', 'Dem'], ['37.0', '52.0', '7.0', '3.0', '25118', 'Marquette Law School', '2016-08-04', '2016-08-07', 'Likely Voters', '683', 'Live Phone', 'Nonpartisan', 'None'], ['41.0', '45.0', '9.0', '6.0', '24879', 'Marquette Law School', '2016-07-07', '2016-07-10', 'Likely Voters', '665', 'Live Phone', 'Nonpartisan', 'None'], ['36.0', '41.0', '11.0', '12.0', '24768', 'CBS/YouGov', '2016-06-21', '2016-06-24', 'Likely Voters', '993', 'Internet', 'Nonpartisan', 'None'], ['39.0', '47.0', '', '14.0', '24790', 'PPP (D-Americans United for Change/Constitutional Responsibility Project) ', '2016-06-22', '2016-06-23', 'Likely Voters', '843', 'IVR/Online', 'Sponsor', 'Dem'], ['36.0', '47.0', '7.0', '10.0', '24849', "GQR (D-Democracy Corps/Women's Voices Women Vote)", '2016-06-11', '2016-06-20', 'Likely Voters', '300', 'Live Phone', 'Sponsor', 'Dem'], ['37.0', '46.0', '13.0', '4.0', '24685', 'Marquette Law School', '2016-06-09', '2016-06-12', 'Likely Voters', '666', 'Live Phone', 'Nonpartisan', 'None'], ['31.0', '43.0', '', '', '24567', 'Public Opinion Strategies (R)/Federation for Children', '2016-05-10', '2016-05-12', 'Likely Voters', '600', 'Live Phone', 'Pollster', 'Rep'], ['34.0', '46.0', '12.0', '9.0', '24316', 'St Norbert/WPR/WPTV', '2016-04-12', '2016-04-15', 'Registered Voters', '616', 'Live Phone', 'Nonpartisan', 'None'], ['37.0', '47.0', '', '17.0', '24195', 'Emerson College Polling Society', '2016-03-30', '2016-04-03', 'Likely Voters', '1198', 'Automated Phone', 'Nonpartisan', 'None'], ['35.0', '49.0', '6.0', '10.0', '24182', 'Fox News', '2016-03-28', '2016-03-30', 'Likely Voters', '1602', 'Live Phone', 'Nonpartisan', 'None'], ['37.0', '47.0', '12.0', '5.0', '24172', 'Marquette Law School', '2016-03-24', '2016-03-28', 'Registered Voters', '1405', 'Live Phone', 'Nonpartisan', 'None'], ['37.0', '48.0', '11.0', '6.0', '23872', 'Marquette Law School', '2016-02-18', '2016-02-21', 'Registered Voters', '802', 'Live Phone', 'Nonpartisan', 'None'], ['38.0', '47.0', '9.0', '6.0', '23623', 'Marquette Law School', '2016-01-21', '2016-01-24', 'Registered Voters', '806', 'Live Phone', 'Nonpartisan', 'None'], ['38.0', '48.0', '9.0', '5.0', '23197', 'Marquette Law School', '2015-11-12', '2015-11-15', 'Registered Voters', '803', 'Live Phone', 'Nonpartisan', 'None'], ['39.0', '50.0', '', '11.0', '22973', 'St Norbert/WPR/WPTV', '2015-10-14', '2015-10-17', 'Registered Voters', '603', 'Live Phone', 'Nonpartisan', 'None'], ['36.0', '50.0', '9.0', '4.0', '22823', 'Marquette Law School', '2015-09-24', '2015-09-28', 'Registered Voters', '803', 'Live Phone', 'Nonpartisan', 'None'], ['35.0', '51.0', '10.0', '4.0', '22596', 'Marquette Law School', '2015-08-13', '2015-08-16', 'Registered Voters', '802', 'Live Phone', 'Nonpartisan', 'None']]

2. polls_average(state,completed_after,completed_before): Given a string representation of a state and two dates formatted like those from the data files, return a list with two string values in it (rounded to two decimal places), representing the Trump and Clinton poll average for all polls for that state in which the end_date falls between the completed_after and completed_before dates (inclusive).

Note that in this data set, dates are stored as strings in the format year-month-day. Thankfully, we can use normal >= and <= comparisons with this format and it works exactly as we think it would.

For example, running polls_average('wisconsin', '2016-09-11', '2016-09-27') should return ['42.25', '44.50'] since it will only use the latest 3 polls from the list shown above.

3. current_winner(poll): Given a list that contains at least 2 fields (the first representing Trump's percentage and the second representing Clinton's percentage - much like what you get from polls_average()), return a string showing the winner and margin, cut off to integer precision.

For example, running current_winner(polls_average('wisconsin', '2016-09-11', '2016-09-27')) should return Clinton +2. If the two candidates are tied, return just the word Tie.

Testing

We highly suggest you test these methods by importing them into another file and testing them out there. For example, you could create a file called testing_polling.py with the following code:

from polling import load_state_polls, polls_average, current_winner

print(load_state_polls('oregon'))
print(polls_average('oregon', '2016-09-11', '2016-09-27'))
print(current_winner(polls_average('oregon', '2016-09-11', '2016-09-27')))

This will allow you to test your polling.py file without adding any extra code to it.

Note that if you have any print statements (even commented out) in your submission, it will not be graded. Further, your submission should not have any code that is not in one of the three functions listed above.

Submission: Please submit one .py file named polling.py to the POTD submission system at https://archimedes.cs.virginia.edu/cs1110/. DO NOT submit any testing files. We only want your polling.py file.

more ...

POTD 12 - scrambled.py

Due: Monday, October 17, 11:00 AM

Write a program called scrambled.py that will take a paragraph of text and return the same paragraph, but with each word's letters scrambled according to the algorithm described below.

Read the following paragraph as quickly as you can and see if you have any problems:

Ardcnciog to rreasech at an Eniglsh utnivriesy, it deos not mtaetr in waht odrer the lertets in a word are, the only iaomnrptt tnihg is taht the frsit and last leettr is in the rihgt pcale. The rest can be a ttaol mses and you can stlil read it wthuoit mcuh issue. Tihs is becsaue we do not raed erevy lteetr by istlef but the wrod as a wlohe.

Now, what's important to note is that while the "research" here isn't terribly solid, the result is still quite interesting. For small-to-medium length words, it does seem to hold true that it is not hard to read a scrambled word with the first and last letters still in the correct location.

You are going to write a program that will take an unscrambled paragraph and then scramble each word like we did above.

Your program should do the following:

  1. Prompt the user for the text to scramble.
  2. Prompt the user for a seed for the random number generator (just like with election.py).
  3. Take each word in that sentence and scramble it using a function you write called scramble_word(word) that takes one word as the parameter and returns that word scrambled.
  4. Put the text back together and print it.

You MUST implement this program by writing a function called scramble_word(word). We will test your code for its presence. The user input and looping to call the function on each word can be done however you like.

You have to follow certain rules when scrambling a word:

  1. The first letter must stay in the first position.
  2. The last letter must stay in the last position.
  3. Punctuation at the end of a word (such as a comma or exclamation point), must also still be at the end of the word, in addition to the last letter of the word also staying in place.
  4. Punctuation in the middle of a word (such as an apostrophe) should move around as if it were any other letter (trust us - this makes the code easier to write).
  5. Note that any word of 3 characters or less does not need to be scrambled.
  6. It is okay if a word is scrambled and happens to come back as the original word.

Here are some hints as to how to do this:

  1. You can convert a string to a list with the command list(str), where str in this instance is the string to convert.
  2. You can add import string at the top of your code to get access to a list called string.punctuation which lets you test to see if a character is a punctuation mark. For example "!" in string.punctuation would result in True.
  3. You can add import random at the top of your code to get access to random.shuffle() which will randomize the items in a list with the line random.shuffle(my_list_to_randomize).
  4. The command "".join(my_list) will convert a list to a str.

An example run would look like this:

Enter your text: We love computer science!
Enter a seed (0 for random): 4
Your scrambled sentence is: We lvoe cetmuopr seincce!

HINT: If you run this and get We lvoe cumeoptr scenice!, then you probably are not casting the input for the seed to an int before using it!

Another example:

Enter your text: Commas, while tough, are doable.
Enter a seed (0 for random): 5
Your scrambled sentence is: Comams, wihle tgouh, are dabloe.

Another example:

Enter your text: Even multiple periods.... can be done!
Enter a seed (0 for random): 4
Your scrambled sentence is: Eevn mlpliute pirodes.... can be done!

Submission: Please submit one .py file named scrambled.py to the POTD submission system at https://archimedes.cs.virginia.edu/cs1110/

more ...

POTD 11 - hangman.py

Due: Wednesday, October 12, 11:00 AM

Write a program called hangman.py that will let the user play Hangman as shown in the examples below.

The user will guess letters until either:

  • They have correctly guessed all the letters in the word.
  • They have incorrectly guessed 6 times.

At each turn, display the player's progress by showing the word they're guessing in all capital letters, with all non-guessed characters replaced by dashes ("-").

Suggested Approach

Here's one possible way to approach this program:

  1. Prompt the user to enter a word
  2. Create a display string with the right number of hyphens (loop and add one for each letter in the target word).
  3. For each letter they guess,
    1. If the letter is not in the target word, count a miss
    2. Otherwise, make a new display string by
      1. loop through the target word's letters
        1. if the letter matches their guess, add it to the new display string
        2. if the letter does not match their guess, copy whatever was in that spot of the old display string over
      2. replace the old display string with the new one
    3. If they have too many misses, tell them they lose; if there are no - left in the display string, tell them they win.

The specific output format is shown in the examples below:

Enter a word: HANGMAN
[-------] You have 6 left, enter a letter: A
Correct!
[-A---A-] You have 6 left, enter a letter: B
Incorrect!
[-A---A-] You have 5 left, enter a letter: C
Incorrect!
[-A---A-] You have 4 left, enter a letter: D
Incorrect!
[-A---A-] You have 3 left, enter a letter: E
Incorrect!
[-A---A-] You have 2 left, enter a letter: F
Incorrect!
[-A---A-] You have 1 left, enter a letter: G
Correct!
[-A-G-A-] You have 1 left, enter a letter: K
You lose! The word was "HANGMAN"

Another example:

Enter a word: COMPUTER
[--------] You have 6 left, enter a letter: E
Correct!
[------E-] You have 6 left, enter a letter: B
Incorrect!
[------E-] You have 5 left, enter a letter: C
Correct!
[C-----E-] You have 5 left, enter a letter: A
Incorrect!
[C-----E-] You have 4 left, enter a letter: P
Correct!
[C--P--E-] You have 4 left, enter a letter: E
Correct!
[C--P--E-] You have 4 left, enter a letter: R
Correct!
[C--P--ER] You have 4 left, enter a letter: M
Correct!
[C-MP--ER] You have 4 left, enter a letter: A
Incorrect!
[C-MP--ER] You have 3 left, enter a letter: T
Correct!
[C-MP-TER] You have 3 left, enter a letter: O
Correct!
[COMP-TER] You have 3 left, enter a letter: U
You win! The word was "COMPUTER"

Another example:

Enter a word: Aa
[--] You have 6 left, enter a letter: a
You win! The word was "AA"

Notes
  • We will only grade you on words and guesses made up of letters in the alphabet.
  • Convert both the word and the guesses to upper case; word Aa and guess a should say You win! The word was "AA".
  • If the user guesses a letter twice, handle it the same as the first time. If it initially matched a letter in the string, it should still count as a match and not as a miss. If it was initially a miss, it will count as another miss. This is shown in the examples above.
  • You may assume that the user only types single-letter guesses.

Submission: Please submit one .py file named hangman.py to the POTD submission system at https://archimedes.cs.virginia.edu/cs1110/

more ...

POTD 10 - election.py

Due: Monday, October 10, 11:00 AM

Write a program called election.py that will simulate the 2016 Presidential Election based on five swing states.

Numerous media outlets try to predict the likelihood of a particular result in 2016 election based upon taking the current polling data and running thousands of simulations. You are going to do a much smaller, simpler version of this type of simulation in this POTD. We will only use the values from five states along with the current likelihood of each candidate winning these states from fivethirtyeight.com.

Here is some code to start with (you should put this at the top of your election.py):

# states are VA, FL, PA, CO, OH (in that order)
state_chances_for_trump = [.238, .569, .304, .324, .634]
electoral_votes_by_state = [13, 29, 20, 9, 18]

For example, based on the code above, Trump has a 23.8% chance of winning Virginia's 13 electoral votes. You can assume Clinton has the corresponding 76.2% chance - we will ignore third party candidates to keep this simple (sorry Gary Johnson fans!).

To properly simulate this, your program will need to generate a random number for each state for each run of the simulation you want to do. You will use random.random() to generate a decimal number between 0 and 1. If the number that is returned is less than or equal to the value given in the state_chances_for_trump list, then Trump wins the state and those electoral votes. Otherwise, Clinton wins the electoral votes. For example, consider Virginia again. Trump has a 23.8% chance of winning the state, or .238. random.random() will generate a number somewhere between 0 and 1. Thus, any number that happens to be between 0 and .238 represents a run that successfully hits within that 23.8% chance. Conversely, Clinton wins with any number greater than .238, representing her 76.2% chance.

Testing a program with a random number generator can be tricky. However, it is possible to ensure the same numbers come up each time by "seeding" the random number generator. When you seed a random number generator, it will then use that number as the basis to generate all of its random numbers. Using the same seed will give the same numbers each time. By default, random.random() uses the current system time as its seed. Your program should have the ability to be completely random or accept a seed for testing.

Your program should do the following:

  1. Prompt the user for how many simulations it should run.
  2. Prompt the user for an int to seed the random number generator. If the users provides a 0, then the system should be completely random.
  3. The system should then create a random number for each of the five states and tally up the electoral votes for each candidate, picking a winner for that simulated election.
  4. Over the course of all simulated election runs, your program should keep track of how many election each candidate wins (by having the most electoral votes), to provide an overall percentage chance of winning the election. You calculate this by dividing the number of simulated elections a candidate wins by the total number of simulations you run.

To seed your random number generator, you can use code that looks like this:

seed = int(input("Enter a seed (0 for random): "))
if seed != 0:
    random.seed(seed)

After this code is run, random.random() will generate numbers based upon either your seed or the current system time if the if statement is not triggered.

You do not need to do any extra formatting on any numbers used in this program.

An example run might be:

How many simulation runs?: 5
Enter a seed (0 for random): 3
Run 0: Trump wins with 60
Run 1: Trump wins with 69
Run 2: Clinton wins with 60
Run 3: Clinton wins with 76
Run 4: Trump wins with 47
Chance of Trump winning: 0.6
Chance of Clinton winning: 0.4

Another run might be:

How many simulation runs?: 7
Enter a seed (0 for random): 13
Run 0: Clinton wins with 71
Run 1: Trump wins with 80
Run 2: Trump wins with 49
Run 3: Trump wins with 58
Run 4: Clinton wins with 89
Run 5: Clinton wins with 60
Run 6: Trump wins with 47
Chance of Trump winning: 0.5714285714285714
Chance of Clinton winning: 0.42857142857142855

Another run might be:

How many simulation runs?: 5
Enter a seed (0 for random): 0
Run 0: Clinton wins with 51
Run 1: Clinton wins with 51
Run 2: Clinton wins with 47
Run 3: Clinton wins with 51
Run 4: Trump wins with 80
Chance of Trump winning: 0.2
Chance of Clinton winning: 0.8

You MUST use random.random() and random.seed() to generate your random numbers and seed so we can test your program effectively!

Submission: Please submit one .py file named election.py to the POTD submission system at https://archimedes.cs.virginia.edu/cs1110/

more ...

POTD 9 - credit_card.py

Due: Friday, October 7, 11:00 AM

Write a program called credit_card.py to compute if a given number is a valid credit card number.

Credit card numbers have what is called a check digit. This is a simple way of detecting common mis-typings of card numbers. The algorithm is as follows:

  1. Form a sum of every other digit, including the right-most digit; so 5490123456789128 sums to 8+1+8+6+4+2+0+4 = 33
  2. Double each remaining digit, then sum all the digits that creates it; the remaining digits in our example (5 9 1 3 5 7 9 2) double to 10 18 2 6 10 14 18 4, which sums to 1+0+1+8+2+6+1+0+1+4+1+8+4 = 37
  3. Add the two sums above (33+37 = 70)
  4. If the result is a multiple of 10 (i.e., its last digit is 0) then it was a valid credit card number.

An example run might be:

Type a credit card number (just digits): 1
1 is not a valid credit card number

Another run might be:

Type a credit card number (just digits): 240
Yes, 240 is a valid credit card number

Another run might be:

Type a credit card number (just digits): 9548
Yes, 9548 is a valid credit card number

Another run might be:

Type a credit card number (just digits): 5490123456789129
5490123456789129 is not a valid credit card number

Submission: Please submit one .py file named credit_card.py to the POTD submission system at https://archimedes.cs.virginia.edu/cs1110/.

more ...

POTD 8 - syllables.py

Due: Friday, September 30, 11:00 AM

Write a program called syllables.py that reads a word and prints the number of syllables in the word. For this program, assume the following rules are the only ones you need to determine the number of syllables (there are some special case words that do not follow these rules and we will NOT test for those):

  • Each vowel (a,e,i,o,u,y) counts as 1 syllable except as noted below
  • A sequence of adjacent vowels count as 1 syllable
  • An 'e' at the end of a word does not count
  • If the program determines there are no syllables, then set the count to 1 syllable

Here are some examples:

Please give me a word: harry
The word harry has 2 syllables.

Another example:

Please give me a word: hairy
The word hairy has 2 syllables.

Another example:

Please give me a word: hare
The word hare has 1 syllables.

And one more example:

Please give me a word: the
The word the has 1 syllables.

Submission: Please submit one .py file named syllables.py to the POTD submission system at https://archimedes.cs.virginia.edu/cs1110/.

more ...