simulate.py: 11 points
At this point, any file can import opinion
and leverage the Person
class that you wrote. Let’s implement an example of that!
The goal of Part 2 of the lab is to gain experience working with instances of classes. In the file simulate.py
you will build a simulation which does the following steps:
To help you accomplish this goal, we’ve built some additional tools in the module opinion_helper
and imported them into your starter code for simulate.py
. The two steps below help you learn how to use them!
from X import Y
You’ll notice that instead of import opinion_helper
at the top of simulate.py
, we’ve used a command similar to from opinion_helper import print_relationships
. This command helps us only import some of the methods and functions from opinion_helper.py
and also means we can call them directly by name (i.e. circle(12)
) rather than opinion_helper.circle(12)
.
If you want to import any functions that are not already imported, just add a comma and the function name to the existing import
statement.
The first tool we’ve imported for you is print_relationships(population)
which, given a population (list of Person
objects), prints the relationships between the members as an adjacency matrix. The first row below says that Ang has befriended both Boone and Charlie.
Ang Boone Charlie
Ang 0 1 1
Boone 0 0 1
Charlie 1 0 0
In simulate.py
, add code to the main
method to create three Person
objects to represent Ang (opinion: 0), Boone (opinion: 1), and Charlie (opinion: 0). Assign their friendships to match the connections in the table above using the class methods you wrote in Part 1.
Check your work by making a list called population
which contains all three people and pass population
to the print_relationships
function.
Reminder
Please commit and push your changes.
The second tool we’ve built for you is the class SocialMap
. SocialMap
is designed so that we can draw the connections among friends and see how people’s opinions change over time (all using the picture
module!). The constructor for SocialMap
takes a single parameter - the “population” of the social network as Person
objects. Once constructed, your social network will automatically be displayed.
To see the visualization used in this portion of the lab, you’ll need to use the Ports
tab to open a live view window over port 6080
, like you did in Lab 4. If you need a reminder, please refer to the lab 4 warmup for detailed instructions on how to do this. As in previous labs, the password is csci
.
Readme
Using SocialMap
with your social network has three steps:
SocialMap
class with your population and assign it to a variable. This will display the network.
For instance,network = SocialMap(population)
animate_update
method on your instance of SocialMap
, with one of the people in your list as a parameter. Repeat this step as many times as you want using a for
loop (we recommend 25).print_results
method to see everyone’s opinion after the animation is over.input('Please hit enter/return when you want to close the visualization.')
statement.Now let’s put the Readme above into practice with the social network containing Ang, Boone, and Charlie! Just like described above, the steps are:
SocialMap
with the Ang, Boone, and Charlie population.SocialMap
to call the animate_update
method on a random Person
(i.e. one of Ang, Boone, or Charlie) each time.print_results
to see how the simulation has changed people’s opinions.Reminder
Once you’ve completed the steps above, commit and push your changes.
Note that the simulation always tries to make sure people (nodes in the graph) don’t visually overlap. For more complex simulations, it may take a moment for the graph to setup - feel free to refresh your browser window if it’s taking too long!
Make sure you understand how “befriending” each other turns a list of people into a network, and how to display a SocialMap
, before you continue. In the next section, we will follow a similar process as above to generate and simulate social networks with new shapes.
Note: you’ve demonstrated that you can access your own, bespoke class from another file and use it, as well as being able to use it together with the opinion_helper.py
functions. Great work.
Having implemented our visualizations, we will now make our program simulate a few pre-formed networks at the user’s request. This will be similar to menus we’ve created in previous labs, where the user chooses an option by number. However, in this case we will not use the input function. We’ll use the command line, which is a much more general method in software engineering to obtain user choice. This looks the following way:
python3 simulate.py 1
In this example, the user is running our program, and requesting network number 1 among the list of options. More details on how to get user input from the command line are below.
First, more details on what the program will do. You will need to support creating four different social network options via the command line:
Every Person
object that you create should have a random opinion (with the exception of Ang, Boone, and Charlie). This is the built-in behavior for the example networks.
The table below lists functions you may find helpful for creating interesting example networks. These functions create populations (i.e. interesting combinations of Person
objects) - you’ll still need to call SocialMap
on them to visaulize them. These functions are defined in opinion_helper.py
- you do not have to write them yourself. They do the work of generating Person
objects and befriending each other.
To test out how they work, you can use print_relationships
, as below, before visualizing them with SocialMap
:
population = circle(15)
print_relationships(population)
The table below describes what each of the functions does - you should not need to consult opinion_helper.py
yourself to be able to use them. Each of them returns a population.
The default value of n
in the below networks is 10, but you’re welcome to specify any small-ish n
you’d like.
Function | Description |
---|---|
circle(n) | Returns a population of n people all befriending each other in a circle. |
divided_circle(n) | Returns a population like the circle above, except two people opposite each other in the circle each have a friend with an opposing view who is outside the circle. |
mutual_friendship_line(n) | Returns a population where everyone on the line likes the people on either side of them, except the two people on the end, who have opposite opinions from each other and don’t befriend anyone |
asym_friendship_line(n) | Returns a population where everyone befriends the person to one side of them, all the way down the line. |
pop_star(pop) | Given a population, randomly select one person to be a pop star, whose opinion is now seen by the whole world. Returns the new population. |
Note that unlike the other functions, pop_star
augments existing populations. Make sure you’ve already created population lists to use before choosing to call it!
Remember that your fourth network option should be your own idea. You can use functions from opinion_helper.py
to help generate your network, but your own code should add at least one person and their connections, or some friendship connections should manually be added.
How can we support user input from the command line? Well, if you add:
import sys
at the beginning of your program, you’ll get access to the variable sys.argv
, which is a list of the arguments passed to Python. The first of these is always the name of the program itself. But if you were to run:
python3 simulate.py 1 a
and that program included the statement print(sys.argv)
, we’d get as output:
['simulate.py', '1', 'a']
Note that all values in sys.argv
are strings by default. Given this, and possibly judicious use of the int()
function, you should be able to get all the input you need from command line arguments.
We want the user to give us exactly two command line arguments. Firstly, the name of the program (what they normally give us - you don’t need to do anything fancy to handle this) and a single numeric argument which represents which social network the user would like to display.
Now that we have an overview of how command line arguments work, let’s talk about how we’ll use them to handle user choice in this lab:
main
method of simulate.py
, you should check that the arguement given in the second position (index 1) is of type int
, for example using choice = int(sys.argv[1])
within a try
statement.except
) and print a message explaining the problem, then exit the program completely using sys.exit(1)
so the computer knows something went wrong.Reminder
Take a moment to commit and push your changes.
If the user provides valid command line input, then we have a valid index of sys.argv
that represents the user’s chosen network! Let’s process it appropriately:
Check if the user entered 1
as a command line argument. If they did, generate the network from the example, with Ang, Boone, and Charlie.
For each of the other three options, generate the network you’ve chosen for that option. This should be reminiscent of the menus you created in previous labs. The main difference is that the choice is read before the program even starts.
Finally, create an instance of SocialMap
with your population and loop over the animate_update
function just as you did in Step 2. Make sure to pick a random Person
from the population to update each time!
To gain full credit for Part 2 of this lab, you should have:
n
as needed to see the full simulation for each network!Reminder
Commit and push your changes before you move on.