Hw3pr1part0

Hw3pr1part0

Lab 3 Part 0: Planning and Setup — starting files for download

You may have noticed that this task (programming Lights-On) is bigger than what we’ve asked you to do so far. This program will require more than one function, and you will have to do some planning about how to organize the data the game needs to keep track of and how the functions interact and modify this data.

Here is a link to the starter files for this lab.

Downloading a zip file and unzipping it

To start, download from the above link and unzip the files, perhaps most easily on your Desktop in your home directory.

On Linux do this by right-clicking on the above link and selecting “Save Link As…”. Select “Desktop” for where to place the zip archive file and click “Save.” You should see the file hw3pr1.zip on your desktop. Now double click it and a window should open up. Click on hw3pr1 to highlight it then click “Extract.” In the new window that appears, click “Extract”. This should place a folder called hw3pr1 on your desktop. Open the folder and double click on hw3pr1.py and that should start IDLE.

If you’re not on Linux, unzipped those files, start IDLE, and navigate into the folder and open the hw3pr1.py file. You’ll see a standard header where you should add your name, lab section info, etc.:

'''
Names: You and your pair's names
hw3pr1.py - Lab problem: "Lights On!"
Lab Instructor: Enter your lab instructors name
Lab Time: Enter the day/time of your lab
'''

# Most of your Lab 3 code will go here:

A quick note on the graphics stuff…

Leave the graphics code commented out until the final part of this lab… Then (and it’s entirely optional), you’re welcome to connect them to your lights-on game. For the time being, you can simply place your lab code in the space below the comment that says

# Most of your Lab 3 code will go here:

For now, you’ll consider approaches to the game of “Lights-On,” and then you’ll implement them by composing small pieces and developing intuition for how they work.

Planning your program

Although we will lead you through the decomposition of this problem, we’d like you to do some brainstorming to help you practice breaking a problem down into smaller pieces. Without looking ahead, in comments at the top of that file, answer the following:

  • What data will your program need to keep track of?
  • What will your program need to do with that data?

Try to be specific, describing what you could do with a very short function (e.g.,one of the things your program will need to do might be “Take input from the user about which light they want to toggle.”) Remember that you can use Python’s per-line comment character, #, or you can simply place your comments in a triple-quoted string in your hw3pr1.py file.

"""
like this
"""

Implementing the program, piece by piece

A central piece of data to keep track of is the current state of the board. You will have to modify this data after each turn, in response to the user’s input. Remember that we are working with a 1D version of the game, where the lights exist in a row, rather than a grid.

We will use a list to store the current state of the board. We will not yet implement the data modifications for Lights-On, nor will we respond to user input — yet. That will come later. The purpose of this section is simply for you to practice modifying the values in a list.

Code to start with

Copy this code into your hw3pr1.py file:

import time           # provides time.sleep(0.5)
from random import *  # provides choice([0,1]), etc.
import sys            # larger recursive stack
sys.setrecursionlimit(100000) # 100,000 deep - in theory

def runGenerations(aList):
    """ runGenerations keeps running the evolve function...
    """
    print(aList)            # display the list, aList
    time.sleep(0.5)         # pause a bit
    newList = evolve(aList) # evolve aList into newList
    runGenerations(newList) # recur

def evolve(aList):
    """ evolve takes in a list of integers, aList,
          and returns a new list of integers
          considered to be the "next generation"
    """
    n = len(aList)  # n now holds the length of the list aList
    newList = [setNewElement(aList, i) for i in range(n)]
    return newList

def setNewElement(aList, i, x = 0):
    """ setNewElement returns the NEW list's ith element
         input aList: any list of integers
         input i: the index of the new element to return
         input x: an extra, optional input for future use
    """
    # this returns the ith element of the new list! That is, newList[i]
    return aList[i] + 1

One note on this code: the x=0 in the third input to function setNewElement is a default input. If you provide a third input to setNewElement, the value you provide becomes x. However, if you do not provide a third input, the value x = 0 is used instead. Here, x isn’t used, though it will be in the future.

What to try

Save and load your code with F5. Then, at the Python shell prompt, run

>>> runGenerations([1, 2, 3])
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
[5, 6, 7]

Stopping it…    You’ll need to type control-c to stop the function — otherwise it will run until its memory runs out.

 Write a comment of 2–3 sentences describing what’s happening in the above example. Be sure to include a brief description of how each of the three functions contributes to the behavior. Again, remember that you can use Python’s per-line comment character, #, or you can simply place your comments in a triple-quoted string in your hw3pr1.py file.

"""
like this
"""

NOTE: To succeed in this lab, it is extremely important that you understand exactly how and why runGenerations works. If you aren’t 100% certain you understand what’s going on, ask for help. Later problems will depend on your understanding of runGenerations, evolve, and setNewElement.

Changing setNewElement

For EACH of the following questions, define a new copy (don’t delete the old one!) of the function setNewElement that produces the desired sequence of lists. There is a completed example in Question 0 in a following section on this page.

Python can have many functions of the same name in a single file. This is sometimes helpful if you want to switch around as you test things. It is the last one in the file — the one furthest down toward the bottom of the file — that will be used when you run that file. This last function “redefines” any others of the same name that appear earlier in the file.

For each of these questions, paste a new setNewElement function at the bottom of your file, and then change it to match the behavior you want. That way, all of the intermediate versions will still be in your file (but only the last will be used).

Question 0

Write a setNewElement function that yields the following behavior:

>>> runGenerations([1, 2, 3])
[1, 2, 3]
[2, 4, 6]
[4, 8, 12]
[8, 16, 24]
[16, 32, 48]
[32, 64, 96]
[64, 128, 192]

Answer to Question 0

The idea here is that each output element is double the corresponding input element. Thus, the code is the following, simply cut, pasted, and modified from the old setNewElement:

#
# Question 0
#

def setNewElement(aList, i, x=0):
    """ setNewElement returns the NEW list's ith element
    input aList: any list of integers
    input i: the index of the new element to return
    input x: an extra, optional input for future use
    """
    # returns the new ith element, double the previous value
    return aList[i] * 2

Question 1

Write a setNewElement function that yields the following behavior:

>>> runGenerations([1, 2, 3])
[1, 2, 3]
[1, 4, 9]
[1, 16, 81]
[1, 256, 6561]
[1, 65536, 43046721]

Hint: notice that each element is the square of the one above it… Don’t run this one for too long!!

Question 2

This example uses a slightly longer initial list. Write a setNewElement function that yields the following behavior:

>>> runGenerations([1, 2, 3, 4, 5, 42])
[1, 2, 3, 4, 5, 42]
[42, 1, 2, 3, 4, 5]
[5, 42, 1, 2, 3, 4]
[4, 5, 42, 1, 2, 3]
[3, 4, 5, 42, 1, 2]
[2, 3, 4, 5, 42, 1]
[1, 2, 3, 4, 5, 42]
[42, 1, 2, 3, 4, 5]
[5, 42, 1, 2, 3, 4]

Note the returned value should be the value from the old list, aList, with one index to the left (lower) than the current index. Thus,the return line will be

return aList[SOMETHING]

where SOMETHING is a very short expression involving i and 1.

Question 3

Write a setNewElement function that yields the following behavior:

>>> runGenerations([1, 2, 3, 4, 5, 42])
[1, 2, 3, 4, 5, 42]
[2, 3, 4, 5, 42, 1]
[3, 4, 5, 42, 1, 2]
[4, 5, 42, 1, 2, 3]
[5, 42, 1, 2, 3, 4]
[42, 1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 42]
[2, 3, 4, 5, 42, 1]

Hint: this is the opposite of the previous example. However, depending on how you implement it, you may need an if and an else to handle the very last column.

Question 4: A random list generator…

Write a setNewElement function that yields a random list of 0s and 1s with each generation. It completely ignores the input list! For example (and lots of other behaviors could occur, as well):

>>> runGenerations([1, 2, 3, 4, 5, 42])
[1, 2, 3, 4, 5, 42]
[0, 0, 1, 1, 1, 0]
[0, 0, 1, 1, 0, 0]
[1, 0, 0, 1, 0, 0]
[0, 1, 0, 1, 1, 0]
[0, 0, 0, 1, 0, 0]

Reminder

The function that chooses an element randomly from a list is called as follows:

choice([0, 1])

That’s all you’ll need!

Call your instructor or TA and

?Get checked 0?

[Check the student’s program for Questions 2, 3, and 4 by commenting out the appropriate setNewElement function.]

The next part of the lab will build on this randomly-evolving behavior.

Click here to continue with the next part of the lab. Be sure to continue with the same hw3pr1.py file.