Lab 10: Using and Designing Classes
--- FAQ ---
Goals
After the lab, you should be proficient at
- using already defined classes
- creating and testing your own classes from a specification
- developing a larger program (set of classes) to solve a data management problem
Deadlines Update
We will have a staggered deadline for this lab:
- For Friday, you will turnin your assignment electronically.
You should have completed up through the
SocialNetwork's
addPeople
method and tested all the methods you implemented. - Before lab on Tuesday (later than what was discussed in class, in case that's helpful), you should finish the assignment and submit it electronically as well as print it out.
- No broader issue for this week.
Objective: Set Up
- Set up the help client:
run runHelpClient &
- Instead of creating a lab10
directory, copy
the entire
/csdept/courses/cs111/handouts/lab10
directory and all its contents to yourcs111
directory.
Review
Review the slides for today's lab.
For this lab, you'll use "real" program names instead of the "lab10.x.py" names we typically use.
Objective: Most Common Names
Recall in Lab 9, we were processing the names of Washington and Lee students. The reason we couldn't easily figure out the most common names is because we couldn't tie the name and the number of occurrences together. We want to sort by number of occurrences, but, given the number of occurrences, we can't look up the name that has that number of occurrences. When we want to package and encapsulate data together, that calls for a new data type.
Objective: Using a class (30)
Open freq.py
and read through what
the FrequencyPair
class represents. What is the data for
the class? What is its functionality? Then, check out the test function.
In the Python interpreter, import freq, then
run help(freq)
so you can see the API.
No, seriously, read through the FrequencyPair class and the test code. How does it work?
Putting it all together. This exercise
illustrates how you can use Python to generate graphs. You will
use the FrequencyPair
class to print out the name
frequency results that can be used by another Python program to
generate graphs.
Copy lab9.5.py
into this directory and name it mostCommonNames.py
.
There are two
alternatives for leveraging FrequencyPair
s to solve
the problem:
- (More object-oriented practice) Modify the program so
that the dictionary maps the key (the name) to the value
(the
FrequencyPair
). When the program sees a name again, update theFrequencyPair
's count.Then, get the
values
from the dictionary, which you should make into alist
ofFrequencyPair
s.OR
- Go through the dictionary,
creating
FrequencyPair
s from the mappings, and adding them to a list.
After you have a list of FrequencyPair
s:
- Sort the list by the
FrequencyPair
's count (the default way to sort), following the appropriate example in theFrequencyPair
's test function. - Reverse the list so that the objects are in the order of greatest to least
- Write the list to a file, one at a time, in the following
format:
<name> <count>
For example, an output file for male first names could look like
James 12 John 9 Robert 7 ...
The data above is not the correct values for the W&L data.
- Save your output files for each input file in the
data
directory. You should name the summary files appropriately, such asfemale_fnames_freq.dat
. (You can name the files either in your program or using Linux commands.) With proper use of functions, you should be able to easily modify the program to handle all four input files at once.
Objective: Generating Graphs
Now, we're going to use a Python program to create bar graphs of
the data you generated from your programs
using matplotlib
, which is useful for generating lots of
different kinds of graphs.
Run generateFreqGraphs.py
or
modify autoGraphExample.py
to generate the graphs for
each of your data files. If your data files are set up correctly,
this should be straightforward.
Show the top 5 results for each data file.
Save the graphs in your data
or public_html
directory so that the images
do not affect your printing later.
Objective: Analysis (5)
In comments at the bottom of your mostCommonNames.py
file, analyze the results. The graphs may be helpful or you can
look at the output files you generated.
- What are the 5 most first names, female first names, male first names, and last names?
- Which results are what you expected? Why?
- Which results were most surprising? Why?
There is no output for this part of the assignment.
Objective: Creating a Social Network
Problem: Create FaceSpace, a program to manage social networks. A social network is a set of users, some of whom are friends. You will keep track of the users and allow users to add friends to their social network.
What is provided
Several Python files are provided for you. Don't start from scratch. Leverage these files, which have contain some code.
Data files for the social network.
Testing (15 pts)
Before we discuss the classes you will implement (below), we want to make sure that you know that you need to TEST!
Test your classes before moving on to the user interface. Use
the if __name__ == "__main__"
code segment that you've
used before.
Writing tests helps you isolate problems and debug more easily. If you were to find a problem when you use the user interface, you won't know if there is a problem with your class or with the user interface's use of the class.
Best practices: Implement the constructor and string representation method for each class. Then test them in a test function. Then, implement another method and test it. Continue in this way. This is a little harder for the SocialNetwork class.
If you ask us for help and have not sufficiently tested the other methods you already wrote, we will not help until after you have tested and (perhaps) debugged other methods. Your programs are becoming large, more complex, and more difficult to debug if you don't test each part, individually, to make sure that they are working.
Output
Save the output from executing your test function for each
class in an appropriately named file,
e.g., person.out
Test Data
I have provided a number of test files for the social network that
should be in the data
directory of
your lab10
directory.
The names of the files are named so that you'll know which is the
"people" file and which is the "connections" file. For example, the
smallest social network is made up
of simple.txt
, which contains the people,
and
simple_connections.txt
, which contains the
connections.
Summary of Classes
Organization: The classes should be in their own
modules. The driver/UI program will import
the SocialNetwork
class, and
the SocialNetwork
will import the Person
class. Look at the files that you copied for templates.
The following summarizes the classes and their data and functionality. Descriptions for some methods are linked from the summaries.
Person (25)
This class represents an individual in a social network. You'll need to use this class in your other classes. You can add more methods if you want.
Data:
- unique id (a string)
- name
- friends
Consider: what should the data types of the data be? We discussed one option in class.
Functionality:
- constructor, which takes as a parameter
the
userid
, which is a string. (What should the other data "start out" as? We've done something similar before--where we don't pass in all the initial data for the object--for example with the Deck class. There is a reason I don't want you to pass in any other information; trust me. :) ) - string representation -- consider what would you like to see
displayed if you were to
run
print(person)
. Don't include the list of friends; just the number of friends. - accessors/getters for the data, specifically methods that
get
- userid
- name
- friends
- number of friends
- a "set"ter to update a person's name. You should not allow a
change in id because that will affect
the
SocialNetwork
class adversely, and you don't want that. - add a friend, which takes as input a
Person
object.
Social Network (54)
The provided template includes the method headers, comments, and placeholders for the method body. The placeholders can be removed after you've implemented the method.
Data:
- the people in the social network, specifically a dictionary that
maps an id to the appropriate
Person
object
- constructor, which takes no parameters. What should happen within the constructor?
- string representation - already implemented; requires
getPeople()
method to be completed. hasUserID(userid)
determines if an id is already in use, i.e., returnsTrue
iff the given user id is already used by a person in the social network.addPerson(person)
add a new person to the network. The parameter should be aPerson
object, that Person need not have any friends yet. What should happen if you try to add a Person who has the same id as a Person who is already in the network? You probably shouldn't allow that because a real system wouldn't allow someone else to take your username.- getters/accessors for data, specifically
getPerson(userid)
- get a specificPerson
in the network, using his/her id (What should this method return if there is no person with that id?)getPeople()
- get the people in the network (a list ofPerson
objects)getUserIDs()
- get the list of ids of people in the network (a list ofstr
objects)addConnection(userid1, userid2)
- add a new connection to the network. Parameters should be two ids, which are strings, and the twoPersons
with those ids should be each others' friends after this method executesdisplay
- a "pretty" way to display the social network. (Note that this is different than the__str__
method because accumulating everything into a string is more difficult than just printing it out in a formatted way. Also, we may not want to create such a big string every time we print the social network.) (See below for more information)addPeople(filename)
- add people to the network, from a file (See below for more information)addConnections(filename)
- add connections to the network, from a file (See below for more information)exportPeople(outname)
- exporting the people in the social network to a file in the appropriate format (See below for more information)exportConnections(outname)
- exporting the connections between people in the social network to a file in the appropriate format (This method is provided for you. See below for more information)
The more complex methods are described in more detail below.
String Representation
The string you create should represent the SocialNetwork
but does not need to look as "pretty" as the display method, described
later. In the given implementation, the string representation contains all the
Persons in the social network. (You may want to have some order for the
Persons so that it's easier to find them.)
Displaying the Social Network
Display the people in the network in a pretty, sorted-by-id way. For example:
ID Name Num Friends --------------------------------------------------- 0000 Robert Downey Jr 5 0001 Scarlett Johansson 5 0002 Henry Cavill 6 0003 Ben Affleck 8 0004 Amy Adams 3 0005 Samuel L. Jackson 8 0006 Natalie Portman 8 0007 Chris Hemsworth 7 0008 Chris Pine 5 0009 Jaimie Alexander 9
Adding People to the Network, from a File
See the Lab 10 Slides for the algorithm.
This method will take as input the name of a file and process the file, which contains people that should be added to the social network. (Note that the people do not have friends yet.) To make your code simpler, leverage a method you already wrote.
The format of the file is below:
num_of_users user_id name user_id name ...
Adding Connections to the Network, from a File -- Due Tuesday before lab
See the Lab 10 Slides for the algorithm.
This method will take as input the name of a file and process the file, which contains the connections between people in the social network. Each line of the file contains two ids and represents the people with those ids are friends.
The format of the file is below:
user_id user_id user_id user_id ...
Exporting the people to a file -- Due Tuesday before lab
After updating your social network, you may want to save the network to a file so that you can use it later. There are two parts to the network: the people/users and the connections between the people.
This method should write the people in the social network to a file, named by the parameter to this method. The format of the file is as seen above. Essentially, you want to do the opposite of your method that reads in the people from the file.
A good test of this function is to write out the social network (that you did not update) to another file and then check if the files match.
Exporting the connections to a file
This method handles writing the connections to a file. If you're not using the provided template, copy this method from the template. Note the assumptions about the method names.
FaceSpace Driver Program (16) -- Due Tuesday before lab
This program maintains a SocialNetwork
object and
provides an interface for users to manage the social network. If you
developed the Person
and SocialNetwork
classes correctly, the majority of this program should be getting
input from the user and calling Person
and SocialNetwork
methods.
The bulk of the code has been written for you and is in
the facespace.py
file. If you're having issues with
the user interface, make sure that the given program calls the correct
methods, as named in your class files.
Part 0: Reading in Your Social Network (3)
Your program should allow the user to enter the names of the people
file and the connections file as command-line arguments
(see the lab slides). The program
should call the appropriate methods to read those files to
initialize the social network. If the user does not provide
command-line arguments, the program will attempt to read the default
files,
data/default.txt
and
data/default_connections.txt
.
You must test command-line arguments from the terminal. If you use IDLE, you'll always use the defaults.
For example: python3 facespace.py data/hollywood.txt data/hollywood_connections.txt
Part 1: Interactions with the User (10)
Most of the interactions with the user are implemented for you. You are responsible for implementing the following interactions:
Viewing a person's information:
Which option do you want? v What is the id of the person you want to view? doej doej: Jane Doe has 2 friends
Which option do you want? v What is the id of the person you want to view? a There is no person with id a
Adding a user and displaying the updated network
Which option do you want? u What is the id of the user? doej That user id is already taken. What is the id of the user? ht8 What is the name of the user? Henry the Eighth Henry the Eighth has been added to the network. ************************************* Select one of the following options: (D)isplay the social network (V)iew a person in the social network Add (P)eople to the social network from a file Add (C)onnections to the social network from a file Add a (U)ser to the social network Add a pair of (F)riends to the social network E(X)port the social network (Q)uit the program Which option do you want? d ID Name Num Friends ---------------------------------------- 01 John Doe 2 02 Jane Smith 2 03 James Jones 2 ht8 Henry the Eighth 0
Part 2: Storing the Social Network Before Quitting (3)
Before exiting the program when the user selects the quit option, you should save the social network to the files specified on the command-line/the default files, as appropriate.
Output from FaceSpace
Run FaceSpace in Idle3 (which means that it will not test your use of command-line arguments--I will test that functionality) and save the output, as usual, in an appropriately named file. Make sure you demonstrate the error handling abilities of your code.
Extra Credit
Additional Functionality (up to 12 pts)
We discussed as a class some additional functionality that your classes may have. After you have completed the required functionality, you can add more functionality. (Which class should implement this functionality?) Some of your suggestions included
- Check if another Person is a friend
- Determining who is the most popular/most social
- Determining the number of common friends between two Persons
- Removing friends/people
- Similar enemy functionality
Finishing up: What to turn in for this lab
- Copy
your
lab10
directory into yourturnin
directory. - IDLE and jEdit may create backup files with the "~" extension. Delete these files from your lab directory to save paper when you print.
- Make sure you don't have any
.png
files or data files (i.e., outputs from the common names or exported people files) in thelab10
directory. Those files should be in yourdata
directory.Perform the following steps from your
cs111
directory.
Note that each command below links to a page with more information about using the command. - Create the printable lab assignment, using the
createPrintableLab
command:
createPrintableLab <labdirname> - View your file using the
evince &
command. - Print the file using
the
lpr
command. - Log out of your machine when you are done.
Labs are due at the beginning of Friday's class. You should
hand in the printed copy at the beginning of class, and the electronic
version should be in the turnin
directory before 2:20 p.m. on Friday.
Ask well before the deadline if you need help turning in your assignment!
Grading (125 pts)
- Python programs: 125 pts; see above for breakdown