After the lab, you should be proficient at
Instead of creating a lab10 directory, copy the entire
/home/courses/cs111/handouts/lab10
directory and all its
contents to your labs
directory.
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.
Before we even discuss the classes, we want to make sure that you know that you need to TEST!
Test your classes before moving on to the driver. You'll need to
comment out the calls to the test function(s) when you run the driver
program or you'll need to use the if __name__ ==
"__main__"
code segment that you've seen in example programs.
Save the output from executing the test function in an appropriately
named file.
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: Write the constructor and string representation/print method for each class. Then test them in a test function. Then, write another method and test it. Continue in this way.
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.
You can give these classes different names, as long as they make sense.
Organization: The classes should be in their own
modules. The driver program will import
the SocialNetwork
class, and
the SocialNetwork
will import the Person
class. Look at the files that you copied for templates.
Test each class in a function as you go. Every time you write a new method, test it and verify its correctness.
The following summarizes the classes and their data and functionality. Longer descriptions for some methods are after the summaries.
This class represents an individual in a social network. You'll need to use this class in your other classes. You can rename it and add more methods if you want.
Data:
Functionality:
SocialNetwork
class
adversely, and you don't want that.Person
objectData:
Person
object
Person
objects)str
objects)Person
in the network, using
his/her id (What should this method return if there is no
person with that id?)__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)Person
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.The non-trivial methods are described in more detail below.
The string you create should represent the SocialNetwork
but does not need to look as "pretty" as the display method, described
later. For example, you could just form a string that 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.)
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 life easier, you should leverage a method you already wrote.
An example data file is below:
num_of_users user_id name network user_id name network ...
I have provided a number of test files that should be in
your data-files
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 file is "simple.txt", which contains the people, and "simple_connections.txt", which contains the connections.
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.
An example data file is below:
user_id user_id user_id user_id ...
Display the people in the network in a pretty, sorted way. For example:
ID Name Network Num Friends ------------------------------------------------------------ 1 George Clooney Hollywood 7 10 Jennifer Aniston Hollywood 3 2 Don Cheadle Hollywood 4 3 Matt Damon Hollywood 6 4 Ben Affleck Hollywood 4 5 Julia Roberts Hollywood 4 6 Bernie Mac Hollywood 5 7 Casey Affleck Hollywood 4 8 Brad Pitt Hollywood 4 9 Angelina Jolie Hollywood 1
This method will write your social network to a dot file, which you can then convert into an image that you can view.
If you're not using the SocialNetwork
template I
provided in the handouts
directory, add the
following method to your class:
def exportDotFile(self, outname): "Write a dot graph representing this social network to the file named by outname" graph = Dot() graph.set_type("graph") graph.set_name("SocialNetwork") userids = self.getUserIDs() userids.sort() already_linked = {} for userid in userids: person = self.getPerson(userid) label = makeNodeLabel(person) for friend in person.getFriends(): link = friend.getName() + "." + person.getName() if link not in already_linked: edge = Edge( label , makeNodeLabel(friend) ) graph.add_edge(edge) already_linked[person.getName() + "." + friend.getName()] = 1 graph.write(outname)
Note the methods used in this method. If you used different names in your class, you'll need to modify this method to use the appropriate methods.
To use this method, you must include this statement at the top
of your class: from pydot import *
If you're not using the template I provided, add the following
function inside the module that contains your class. Note: this
is not a method. Also note the Person
method
names/API it assumes.
def makeNodeLabel(person): "Helper function that creates a label for a node in the Dot file" return person.getID() + ". " + person.getName()
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. 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.
This method handles writing the connections to a file. If you're not using the template, copy this method. Note the assumptions about the method names.
def exportConnections(self, outname): """Write the connections to a file, named by outname, in the appropriate format.""" connFile = file(outname, "w") userids = self.getUserIDs() userids.sort() # don't want any duplicate connections in the file, so keep track of # what we've written to the file connections = {} for id in userids: person = self.getPerson(id) for friend in person.getFriends(): connection = person.getID() + " " + friend.getID() reverse = friend.getID() + " " + person.getID() if connection not in connections and reverse not in connections: connFile.write(connection + "\n") connections[connection] = 1 connFile.close()
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.
Let the user know what program they're running.
Your program should allow the user to enter the names of the people
file and the connections file as command-line arguments. The program
will attempt to call the appropriate methods to read those files to
initialize the social network. If you do not give command-line
arguments, the program will attempt to read the default
data-files/default.txt
and
data-files/default_friends.txt
, which are
currently just copies of the 'hollywood' social network.
Your program will repeatedly prompt the user to select an option and then execute the option if it's valid. If the option isn't valid, your program should reprompt for a valid option.
Your user menu should allow the user to execute each of the following options:
Example user menu:
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?
Allow the user to enter lower case or capital letters for options. For example, either "D" or "d" is a valid choice for displaying the social network.
HINT: You could write the option validation with a
bunch of if
statements. Or, you could create a list of
valid options and check if the user's selection is in that list.
Which option do you want? v What is the id of the person you want to view? 1 1: John Doe in W & L 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 aInvalid options and then exporting the network to a dot file:
Which option do you want? s s is not a valid option. Select an option: t t is not a valid option. Select an option: r r is not a valid option. Select an option: x You can export the social network to one of three types of files: 1.) dot file 2.) people file 3.) connections file Which type of file do you want? 1 What is the name of the file that you want to export the social network to? graphs/test.dot Wrote the social network to the file graphs/test.dotAdding a user and Displaying the Updated Network
Which option do you want? u What is the id of the user? 4 What is the name of the user? Henry the Eighth What is the user's network? Royalty 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 Network Num Friends ------------------------------------------------------------ 1 John Doe W & L 2 2 Jane Smith W & L 2 3 James Jones W & L 2 4 Henry the Eighth Royalty 0Adding a connection between people and displaying the updated network
Which option do you want? f What is the userid of the first friend? 3 What is the userid of the second friend? 4 Added the connection between 3 and 4 ************************************* 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 Network Num Friends ------------------------------------------------------------ 1 John Doe W & L 2 2 Jane Smith W & L 2 3 James Jones W & L 3 4 Henry the Eighth Royalty 1
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.
Run FaceSpace in Idle (which means that it will not test your command-line arguments) and save the output, as usual, in an appropriately named file.
You'll show the graphs of the social network for one small (~25 people) and one medium (~50 people) social network on a web page. You can use the sets of data files I gave you or you can create your own social networks.
dot
I provided a method that writes your social network into
a .dot
file. To view the social network, we
need to translate that .dot file into a graph.
The dot
command does that work for us. We
can create the graph into an image file (e.g., png) or into a PDF
file.
The general format of the command is:
dot -T<filetype> -o <outputfilename>
<dotfile>
For example, to generate a PDF file for the
file network.dot
, I would execute the
command:
dot -Tpdf -o network.pdf network.dot
Or, to generate a PNG file for the same network.dot
, I would execute the
command:
dot -Tpng -o network.png network.dot
To view PDFs, you can use the gv
command
and to view PNG files, you can use the xv
command.
An example image from the Hollywood social network:
public_html
directory.lab9.html
file into a file
called lab10.html
in the public_html
directory.public_html
directory.You may want to shrink the image displayed using the
width
or height
attributes and a size, in
pixels. For example:
<img src="social_network.png" width="500">
would make the image display 500 pixels wide and the height
would change proportionally. If you right-click and "view image", the
image will be its original size.
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
Did you create social network files that you want to let others test? This includes the "people" file as well as the "connections" file. If so, mail it to me, and I will post in on the web page.
turnin
directory.
(Review the UNIX handout if you don't
remember how to do that.)
printLab.sh
command to create a file to
print out. You should probably print from the labs
directory. You may get a warning about the directory containing
subdirectories. As long as you don't get an
enscript
error about unknown special escape, you
should be okay.
gv
command, such as gv lab10.ps
Print the file using the lpr
command
introduced in the first lab.
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 1:20
p.m. on Friday.
Ask well before the deadline if you need help turning in your assignment!