research ideas - northwestern...

86
EECS110 Homework 5, Spring 2009 Due: 11:59pm on Sunday May 17, 2009 Submission: submit your solutions at the submissions server If you are working on lab problems, please go to: http://cs.northwestern.edu/~akuzma/classes/EECS110-s09/ lab/lab5/lab5.htm You should do the first problem for Lab5. Problems: Problem 1: The Game of Life (hw5pr1.py) [50 points; individual or pair] Homework 5, Problem 1: The Game of Life [50 points; individual or pair] Submission: Submit your hw5pr1.py file to the submission server

Upload: phungnhu

Post on 16-Apr-2018

218 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

EECS110 Homework 5, Spring 2009

Due: 11:59pm on Sunday May 17, 2009

Submission: submit your solutions at the submissions server

If you are working on lab problems, please go to:http://cs.northwestern.edu/~akuzma/classes/EECS110-s09/lab/lab5/lab5.htmYou should do the first problem for Lab5.

Problems:Problem 1: The Game of Life (hw5pr1.py) [50 points; individual or pair]

Homework 5, Problem 1: The Game of Life

[50 points; individual or pair]

Submission: Submit your hw5pr1.py file to the submission server

The Game of Life is a cellular automaton invented by John Conway, a mathematician from Cambridge. The game of life is not so much a "game" in the traditional sense, but rather a process that transitions over time according to a few simple rules. The process is set up as a grid of cells, each of which is "alive" or "dead" at a given point in time. At each time step, the cells live or die according to the following rules:

1. A cell that has fewer than two live neighbors dies (because of loneliness)

2. A cell that has more than 3 live neighbors dies (because of over-crowding)

3. A cell that is dead and has exactly 3 live neighbors comes to life

4. All other cells maintain their state

Although these rules seem simple, they give rise to complex and interesting patterns. For more information and a number of

Page 2: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 2 of 43

interesting patterns see http://en.wikipedia.org/wiki/Conway's_Game_of_Life.

In this lab, you will implement a Python program to run the Game of Life.

Getting started with life!

As always, it is important to break the problem down into pieces and develop the program in stages so that others can understand the code and so that you can ensure that each piece is correct before building on top of it. We will break this problem down into the following steps:

1. Creating a 2d array of cells

2. Displaying the board (in various colors) and updating it with new data

3. Allowing the user to change the state of the cells

4. Implementing the update rules for the "Game of Life"

5. (Optionally) Running and stopping the simulation

Before you start, you need to develop a scheme for keeping track of your data. Basically, the data you need to maintain are the states of all of the cells in the board. We suggest that you keep track of this data in a 2D array of integer values, where 0 represents an empty (off) cell and 1 represents a live (on) cell.

Creating a 2d board of cells

First, in your hw5pr1.py file, copy and test this example function:

def createOneRow( n ):""" returns rows of n zeros... You might usethis as the INNER loop in createBoard """R = []for col in range(n):

R += [0]

Page 3: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 3 of 43

return RThis function offers a starting-point for creating one-dimensional lists -- but the same idea applies for building nested list structures arbitrarily deep.

Building on this example, write a function named createBoard( width, height ) that creates and returns a new 2D list of height rows and width columns in which all of the data elements are 0 (no graphics quite yet, just a Python list!). For example,

>>> createBoard( 3, 3 )[ [0,0,0], [0,0,0], [0,0,0] ]One approach to createBoard is to use a pair of nested loops: the outer one for the rows, and the inner one for the columns (note that you can use createRow for the inner loop. Then, the overall 2d array would accumulate those rows one at a time (within the loop) until it was the correct size. Note that just as

R += [0]

adds a zero to the end of the list (row) R, by the same token,

B += [ [0,0,0] ]

adds a row of three zeros to the end of list (board) B. When you write createBoard, that row will have a name (maybe R), rather than hand-typed values.

Displaying your 2d board of cells

You no doubt noticed that when Python prints a 2d list, it blithely ignores its 2d structure and flattens it out into one line (perhaps wrapping, if needed). In order to display your board in 2d using the csplot graphics module, you will need to download csplot.py from this link. =csplot.py= has changed from previous weeks so be sure to delete any old versions you have and then re-download it.

A convenient place to download csplot.py is to your desktop. Though the desktop is easy, any folder you choose is OK. Wherever

Page 4: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 4 of 43

you put it, you will need your hw5pr1.py file to be in the same folder as csplot.py.

Next, in order to use the functions in csplot, include the following line at the top of your hw5pr1.py file:

import csplot

Now, once you load your hw5pr1.py file into the Python shell, you should be able to create and display a 2d array with

>>> B = createBoard(10,10)>>> csplot.show(B)

You will see a rather desolate-looking board:

Recall from a few weeks ago that this CS plot window will not close unless you use the done() command. To refresh the window you can type:

>>> csplot.update()

Page 5: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 5 of 43

To close the window, type:

>>> csplot.done()

and then click the red X in the corner of the cs plot window.

Adding patterns to your 2d board of cells

In order to get used to using 2d arrays of data and writing functions that modify arrays rather than return them, copy this function named update1( B ) into your file:

def update1( B ):""" Takes an empty board as input and modifies that

boardso that it has a diagonal strip of "on" cells"""width = len(B[0])height = len(B)

for row in range(height):

for col in range(width):if row == col:

B[row][col] = 1else:

B[row][col] = 0 # else not needed here, but OK

This function, update1 takes as input a blank 2d array of data, B. Then, it changes some of that data so that B becomes a board whose cells are empty except for the diagonal where row == col. Note that it does not return anything. Also note that we determine the height and width of the board directly from the board itself.

Try displaying the result with

>>> B = createBoard(10,10)>>> update1(B)>>> csplot.show(B)

Page 6: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 6 of 43

Warning!! The coordinate system of Python's printing and csplot's graphics system have the rows going in opposite directions. That is, when you print a 2d array (list of lists), the zeroth row is at the top, then the first row is next, and so on. However, csplot uses mathematical coordinates (rows increase along the y-axis and columns increase along the x-axis), so that the zeroth row is at the bottom, the first row is the second-from-bottom, and so on. Thus, when you display this new board, you should get a window that looks something like this:

Based on the example of update1, write a variation named update2( B ) which returns a board of all live cells, except for a one-cell-wide border of empty cells around the entire edge of the 2d array. Copy-and-paste is your friend! For example, when you run

>>> B = createBoard(10,10)>>> update2(B)>>> csplot.show(B)

Page 7: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 7 of 43

you should get a window that looks something like this:

Next, create a function named updateRandom( B ) which takes a board B and mutates that board to contain one-cell-wide border of empty cells around the entire edge of the 2d array, just as in the previous case. However, each of the inner cells should be randomly chosen to be live or empty. Recall that random.choice( [0,1] ) will help here -- and that you will need to include the line import random somewhere near the top of your file.

Page 8: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 8 of 43

Here is one possible such board:

A note on changing cells' colors

You can choose different colors by using a second input called a dictionary to the csplot.show command. For example,

B = createBoard(10, 10)updateRandom(B)d = {0:'green', 1:'blue'} # dictionary of int/color pairscsplot.show(B,d) # optional second argument

Page 9: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 9 of 43

will produce something similar in spirit to this:

Creating a new "board" from an old one...

None of the update functions so far depends on a previous "generation" of cells. For our life game we need to update the cells from one generation to modify a NEW board in the subsequent generation.

Write a function updateReversed( oldB, newB ) that takes an old board and a blank new board and modifies the newB such that each cell is the "opposite" of oldB's cells. That is, where oldB[row][col] is a 1, the new board's value will be a zero - and vice versa. This function should not return anything.

But, keep the outermost edge of cells empty, regardless of their state in the original board - this will help when implementing Life, because it will prevent out-of-bounds errors.

Page 10: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 10 of 43

Recall that you can obtain the width and height from oldB:

width = len(oldB[0])height = len(oldB)

Try out your updateReversed by displaying an example:

>>> B = createBoard(10,10)>>> updateRandom( B )>>> csplot.show( B )>>> newB = createBoard( 10, 10 )# makes newB reference a NEW board...>>> updateReversed(B, newB)>>> csplot.show( newB )

It's important that you first make a NEW array of data to pass into the updateReversed function. You might point out that it would be possible to simply change the input oldB, rather than have two inputs - this is true for the reversed-board example, but not true when implementing the rules of the Game of Life. There, you will need new data on which to place each subsequent generation.

Writing a Life-updating loop

To start updating one generation of cells to the next, read over the following skeleton and then adapt - or simply copy - it into your hw5pr1.py file:

import time

def life( width, height ):""" will become John Conway's Game of Life... """B = createBoard( width, height )updateRandom( B )

while True: # run forevercsplot.show(B) # show current Btime.sleep(0.25) # pause a bitoldB = B # just a reminder for us humansB = createBoard(width, height) # creates a new

board

Page 11: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 11 of 43

updateReversed( oldB, B ) # sets the new board correctly

Be sure to import time, as noted above the function. The while loop here will run forever - or until you hit control-c and will continue to display reversing boards as it goes.

Adding some user input

For debugging and increased user control it will be important to allow the user to specify which cells are on and which are off at the beginning of the simulation. To allow this control, copy and paste the following code at the end of your hw5pr1.py file.

def life( width, height ):""" will become John Conway's Game of Life... """B = createBoard( width, height )csplot.showAndClickInIdle(B)

while True: # run forevercsplot.show(B) # show current Btime.sleep(0.25) # pause a bitoldB = B # just a reminder for us humansB = createBoard(width, height) # creates a new

boardupdateReversed( oldB, B ) # sets the new board

correctly

Here's what should happen when you run this function (e.g. by calling life(10, 10)). You will see a blank 10x10 grid appear, but this grid will not update automatically as before. Instead, you should click on the display window so that it is the current top window. Then, hold down the s key and click inside one or more of the cells in the display. You should see those cells change from live to empty and vice-versa. Once you're ready, close the display window, and you will see another display window appear, starting with the board that you created by clicking (NOT the original blank board) and automatically updating as before.

The Game of Life

Page 12: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 12 of 43

So, for this step, change your life function so that it calls a new function named updateNextLife( oldB, newB ) in place of updateReversed, above. Then, implement the updateNextLife( oldB, newB ) function so that it sets each cell in the new data according to the updating rules based on the old generation, oldB:

1. A cell that has fewer than two live neighbors dies (because of loneliness)

2. A cell that has more than 3 live neighbors dies (because of over-crowding)

3. A cell that is dead and has exactly 3 live neighbors comes to life

4. All other cells maintain their state

As suggested in updateReversed, always keep all of the outer-edge cells empty. This is simply a matter of limiting your loops to an appropriate range. However, it greatly simplifies the four update rules, above, because it means that you will only update the interior cells, all of which have a full set of eight neighbors. You may want to write a helper function, countNeighbors for example, for determining the number of live neighbors for a cell in the board at a particular row and col.

Warnings/hints: there are a few things to keep in mind:

1. Count neighbors only in the old generation oldB. Change only the new generation, newB.

2. Be sure to set every value of newB (the new data), whether or not it differs from oldB.

3. A cell is NOT a neighbor of itself.

4. A 2x2 square of cells is statically stable (if isolated) - you might try it on a small grid for testing purposes

5. A 3x1 line of cells oscillates with period 2 (if isolated) - also a good pattern to test.

Page 13: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 13 of 43

Once your Game of Life is working, look for some of the other common patterns, e.g., other statically stable forms ("rocks"), as well as oscillators ("plants") and others that will move across the screen, known as gliders ("animals/birds").

Optional Extensions

Adding pause/resume (or other user options) [Up to +5 points]

For this optional extension, you can no longer run your code from within IDLE for reasons that are too complicated to explain here. Instead you will need to run python from the command line (e.g., the Terminal, or Shell). Here's how to do this:

Open a terminal window and change your directory to the location where csplot.py and hw5pr1.py are located. Here are brief instructions for PCs and Macs:

PC: Go to the Start menu's Run option and type cmd. Then, type cd Desktop at the terminal window's prompt. (Go to wherever your files are.) Once there, type c:\python25\python -i hw5pr1.py.

Mac: Go to the Applications folder into the Utilities subfolder and open the Terminal application. At its prompt, type cd Desktop. (Go to wherever your files are.) Once there, type python -i hw5pr1.py.

Please ask if you run into any problems with this!

Between runs if you make any changes to your code you will need to reload it into python. The easiest way to do this is to follow these instructions:

Easy ways to exit and reload your Python program: Mac and PC    To leave the python shell, use the shortcuts: control-d on Macs and control-z then enter on PCs. Alternatively, you can type quit() on either system. Then, in order to reload your new hw5pr1.py file, hit the up-arrow key and hit return. That's it!

Page 14: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 14 of 43

Now, onto the extensions...

There is a function in csplot named csplot.getKeysDown() that returns a string with the keys being pressed. In fact, the keys have to be pressed when the focus is on the drawing window -- it's only possible to get that kind of keyboard information from the graphics system (and not the Python shell).

You can use this function in order to set a boolean variable that determines whether or not to run the updating step or to pause it or step it by only one generation. Something like this:

if pause == False: B = createNextLifeBoard( oldB )

where the boolean value pause starts at False, but can be changed as follows:

keysList = csplot.getKeysDown()if 'p' in keysList: pause = True

Warning: do not write another loop inside of the main while loop. What may happen is that the code will get caught in the inner loop and never escape. Or, the inner loop will call nothing except csplot.getKeysDown(), which floods the I/O system with too many calls and causes Python to hang.

So, be sure to keep the csplot.show(B) line and the time.sleep line within your constantly-running while loop -- otherwise, the loop will run too fast, and the calls to csplot.getKeysDown can not keep up.

Try implementing these four key-presses:

'p' in order to pause the generation-updating. 'r' in order to resume the generation-updating. 'q' in order to quit the main while loop (and the program). '1' in order to advance only 1 generation and then pause.

There might be other options you'd like to add for different keys -- for example, you might have a color-swapping key or a key that randomly adds live cells to keep things moving... . Try at least the four keys listed above -- add others as you see fit... .

Page 15: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 15 of 43

Variations on the game of life [up to +5 points e.c.]

Finally, you can choose to implement one of two variations on the game of life.

Variation One: the doughnut    For this variation, remove the margin of empty cells around the board. In this case, the board should have the topology of a doughnut -- so that the left and right edges of the board become neighbors, as do the top and bottom edges. This makes neighbor-counting and avoiding out-of-bounds errors trickier. Yet with a single function that "looks up" the actual location of any given row and col coordinates, it's not too bad.

Variation Two: alien life    Life is considered a 23/3 cellular automaton, because cells survive with 2 or 3 neighbors (the two digits before the slash) and they are born with 3 neighbors (the digit after the slash). Many (perhaps all) of the other survival/birth possibilities have been studied, as well. Some even have names: for example, 1358/357 is called "Amoeba" and 1/1 is called "Gnarl." For this variation on life, choose a different set of survival/birth rules, perhaps from this reference of them and implement a key that switches between John Conway's Game of Life and your chosen set of rules (with another key to go back).

If you have gotten to this point, you have completed Lab 5! You should submit your hw5pr1.py file at the Submission Site.

This is the end of Lab5.

Below is the rest of Homework 5, also available athttp://cs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/homework5.htm

Problem 2: Markov Text Generation (hw5pr2.py) [50 points; individual or pair]

Page 16: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 16 of 43

Homework 5, Problem 2: Markov Text Generation

[50 points; individual or pair]

Submission: Submit your hw5pr2.py file to the submission server

Your goal in this section is to write a program that is capable of generating "meaningful" text all by itself! You will accomplish this goal by writing a Markov text generation algorithm.

Note: Some of the functions shown in the optional problem 4 (hw5pr4.py) below might be very useful for this problem.

Markov Text Generation

Here's the basic idea: English is a language with a lot of structure. Words have a tendency (indeed, an obligation) to appear only in certain sequences. Grammatical rules specify legal combinations of different parts of speech. E.g., the phrase "The cat climbs the stairs" obeys a legal word sequence. "Stairs the the climbs cat", does not. Additionally, semantics (the meaning of a word or sentence) further limits possible word combinations. "The stairs climb the cat" is a perfectly legal sentence, but it doesn't make much sense and you are very unlikely to encounter this word ordering in practice.

Even without knowing the formal rules of English, or the meaning of English words, we can get idea of what word combinations are legal simply by looking at well-formed English text and noting the combinations of words that tend to occur in practice. Then, based on our observations, we could generate new sentences by randomly selecting words according to commonly occurring sequences of these words. For example, consider the following text:

"I love roses and carnations. I hope I get roses for my birthday."

If we start by selecting the word "I", we notice that "I" may be followed by "love", "hope" and "get" with equal probability in this text. We randomly select one of these words to add to our sentence, e.g. "I get". We can repeat this process with the word "get",

Page 17: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 17 of 43

necessarily selecting the word "roses" as the next word. Continuing this process could yield the phrase "I get roses and carnations". Note that this is a valid English sentence, but not one that we have seen before. Other novel sentences we might have generated include "I love roses for my birthday," and "I get roses for my birthday".

More formally, the process we use to generate these sentences is called a first order Markov process. A first-order Markov process is a process in which the state at time t+1 (i.e. the next word) depends only on the states at times t (i.e., the previous word). In a second-order Markov process, the next word would depend on the two previous words, and so on. Our example above was a first order process because the choice of the next word depended only on the current word. Note that the value of the next word is independent of that word's position and depends only on its immediate history. That is, it doesn't matter if we are choosing the 2nd word or the 92nd. All that matters is what the 1st or the 91st word is, respectively.

Your text-analyzer and generator

In the first part of this assignment you will implement a first-order Markov text generator. Writing this function will involve two functions: (1) one to process a file and create a dictionary of legal word transitions and (2) another to actually generate the new text. Here are details on each:

createDictionary

createDictionary( nameOfFile ) takes in a string, the name of a text file containing some sample text. It should return a dictionary whose keys are words encountered in the text file and whose entries are a list of words that may legally follow the key word. Note that you should determine a way to keep track of frequency information. That is, if the word "cheese" is followed by the word "pizza" twice as often as it is followed by the word "sandwich", your dictionary should reflect this trend. For example, you might keep multiple copies of a word in the list.

Page 18: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 18 of 43

The dictionary returned by createDictionary will allow you to choose word t+1 given a word at time t. But how do you choose the first word, when there is no preceding word to use to index into your dictionary?

To handle this case, your dictionary should include the string "$" representing the sentence-start symbol. The first word in the file should follow this string. In addition, each word in the file that follows a sentence-ending word should follow this string. A sentence-ending word will be defined to be any raw, space-separated word whose last character is a period ., a question mark ?, or an exclamation point !

Checking your code...

To check your code, paste the following text into a plain-text file (for example, into a new file window in IDLE): A B A. A B C. B A C. C C C.Save this file as t.txt in the same directory where your hw5pr2.py lives. Then, see if your dictionary d matches the sample below: >>> d = createDictionary( 't.txt' )>>> d{'A': ['B', 'B', 'C.'], 'C': ['C', 'C.'], 'B': ['A.', 'C.', 'A'], '$': ['A', 'A', 'B', 'C']}

The elements within each list need not be in the same order, but they should appear in the quantities shown above for each of the four keys, 'A', 'C', 'B', and '$' .

generateText generateText( d, n ) will take in a dictionary or word transitions d (generated in your createDictionary function, above) and a positive integer, n. Then, generateText should print a string of n words. The first word should be randomly chosen from among those that can follow the sentence-starting string "$". Remember that random.choice will choose one item randomly from a list! The second word will be randomly chosen among the list of words that could possible follow the first, and so on. When a chosen word ends in a period ., a question mark ?, or an exclamation point !, the

Page 19: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 19 of 43

generateText function should detect this and start a new sentence by again choosing a random word from among those that follow "$". For this problem, you should not strip the punctuation from the raw words of the text file. Leave the punctuation as it appears in the text -- and when you generate words, don't worry if your generated text does not end with legal punctuation, i.e., you might end without a period, which is ok. The text you generate won't be perfect, but you might be surprised how good it is!

If your process ever encounters a word that has only appeared as the last word in your training set (i.e., it does not have any words that follow it), you should simply start generating text again with the sentence-start symbol "$" . Here are two examples that use the dictionary d, from above. Yours will differ because of the randomness, but should be similar in spirit.

>>> generateText( d, 20 )B C. C C C. C C C C C C C C C C C. C C C. A

>>> generateText( d, 20 )A B A. C C C. B A B C. A C. B A. C C C C C C.

The text you want to use is up to you. IRS documents like this one (http://www.irs.gov/newsroom/article/0,,id=159925,00.html may be good. Random scenes from Shakespeare might also strike your fancy (http://www-tech.mit.edu/Shakespeare/)

If you have gotten to this point, you have completed problem2! You should submit your hw5pr2.py file at the Submission Site.

Extra Problems:

Problem 3: ASCII Art <:-) (hw5pr3.py) [10 extra points, individual or pair]Practice with nested loops (Difficulty: Easy to Medium)

Homework 5, Problem 3: ASCII Art [10 extra points; individual or pair]

Page 20: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 20 of 43

Submission: Submit your hw5pr3.py file to the submission server

In this assignment you will revisit a classic art form: ASCII art!

Important limitation! For these problems, do not use Python's string-multiplication or string-addition operators. Because our goal is to use loop constructs, use loops to achieve the repetition that those operators might otherwise provide.

The goal of this problem is to solidify further your reasoning skills with loops, and nested loops. For many of the problems (especially the striped diamond), you will have to think carefully about the value of your loop control variable as your loop or loops execute. "Debugging by random permutation" -- that is, arbitrarily changing the values of your loop conditions or variables -- will lead to much frustration... . The path to success on this assignment is to reason carefully about your loops.

Simple ASCII art

printSquare

We'll start simple. Write a function printSquare that takes two arguments, a number n and a character c and prints a square of size n by n on the screen.

e.g.

printSquare( 3, '$' )

$ $ $$ $ $$ $ $

Note the spaces between the characters. This is natural if you use Python's print command followed by a comma.

Page 21: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 21 of 43

It is possible to avoid these spaces that Python insists on. To do so, you will need to use the more complicated function call sys.stdout.write( '$' ), where the '$' can be a variable holding a string as well. To use this, you will need to have the line import sys at the top of your file. However, this is entirely optional. Feel free to use print with the spaces!

printRect

Next, write a function named printRect that takes three arguments, width, height, and symbol, and prints a width by height rectangle of symbols on the screen.

printRect( 4, 6, '%' )

% % % %% % % %% % % %% % % %% % % %% % % %

Again, in this part, and in all remaining parts, the space between the characters is optional, as long as the characters line up correctly.

Answer the following question in comments in a comment or triple-quoted string in your hw5pr3.py file:

Question: What does your printRect function do if you pass it negative numbers as input? Is this a reasonable behavior? If not, modify your code and say what you fixed.

More complex ASCII art

printTriangle

Add a function printTriangle that takes three arguments: width, symbol, and rightSideUp and prints a triangle of symbols on the

Page 22: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 22 of 43

screen. width is a number that determines the width of the base of the triangle and rightSideUp is a boolean that determines whether the triangle is printed right side up (True) or upside down (False).

printTriangle( 3, '@', True )

@@ @@ @ @

printTriangle( 3, '@', False )

@ @ @@ @@

printBumps

Now, use your printTriangle function to write a function called printBumps( num, symbol1, symbol2 ) that will print the specified number of two-symbol "bumps", where each bump is larger than the last, as in the following example:

printBumps( 4, '%', '#' )

%#%% %# ##%% %% % %# # ## ##%% %% % %% % % %# # # #

Page 23: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 23 of 43

# # ## ##

printDiamond

For these "diamond" functions, you may use string multiplication, but only for strings of blank spaces, such as ' '*n or the like. Each visible character should be printed separately, just as in the functions earlier in this problem. Also, you don't have to use the string * operator for strings of spaces, either.

Write a function called printDiamond( width, symbol ) that prints a diamond of symbol whose maximum width is determined by width.

printDiamond( 3, '&' )

& & & & & & & & &

printStripedDiamond

Next, write a function called printStripedDiamond( width, sym1, sym2) that prints a "striped diamond" of sym1 and sym2.

For example:

printStripedDiamond( 7, '.', '%' )

. . % . % . . % . % . % . % . . % . % . %. % . % . % .

Page 24: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 24 of 43

% . % . % . . % . % . % . % . . % . % . .

printCrazyStripedDiamond

Finally, write a function called printCrazyStripedDiamond( width, sym1, sym2, sym1Width, sym2Width) that prints a "striped diamond" of sym1 and sym2 where the stripes can have varied widths. sym1Width determines the width of the stripe made of symbol 1 and sym2Width determines the width of the stripe made of symbol 2.

For example:

printCrazyStripedDiamond( 7, '.', '%', 2, 1 )

. . . . . % . . % . . . % . . . . % . . %. . % . . % . . % . . % . % . . % . . . % . . % . % . .

If you have gotten to this point, you have completed problem3! You should submit your hw5pr3.py file at the Submission Site.

Page 25: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 25 of 43

Problem 4: A program that reads... (hw5pr4.py) [20 extra points; individual or pair]Practice with user menus and string manipulation (Difficulty: Hard).

Homework 5, Problem 4: A program that reads [20 extra points; individual or pair]

Submission: Submit your hw5pr4.py file to the submission server

The Flesch Index (FI) is a numerical measure of the readability of a particular piece of text. Textbook publishers and editors often use it to ensure that material is written at a level appropriate for the intended audience.

For a given piece of text, the Flesch readability, or Flesch index (FI), is given by:

FI = 206.835 - 84.6 * numSyls/numWords - 1.015 * numWords/numSents

where: 1. numSyls is the total number of syllables in the text 2. numWords is the total number of words in the text 3. numSents is the total number of sentences in the text

The FI is simply a linear combination of two text-related ratios, subtracted off of a constant offset. FI is usually reported as an integer, and casting the floating-point result to an integer is completely fine for this purpose.

Here are some resulting readability scores for a few example publications or styles of writing (cited from Cay Horstmann's book, p. 266). It is, in fact, possible to have a negative readability score:

95 - Comics

82 - Advertisements

65 - Sports Illustrated

57 - Time Magazine

Page 26: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 26 of 43

39 - New York Times

10 - Auto insurance policy

-6 - Internal Revenue Code

In this problem you will write a program to compute the Flesch readability score or Flesch Index (FI) for different pieces of text. Because the rules for counting words, sentences, and syllables can be tricky, it is important to allow the user to play with various inputs and see how they decompose into syllables, sentences, and words. For this reason, you will structure this program in a function named flesch() that provides a menu of options for analyzing text.

Example run from a complete flesch program

Here is what the user should see when they run your flesch() function -- changes to the text are OK, but please keep to the option numbers listed here and their functionality, because it will make your program much easier to grade!

Welcome to the text readability calculator!

Your options include:

(1) Count sentences(2) Count words(3) Count syllables in one word(4) Calculate readability(9) Quit

What option would you like?

The first three options will help you troubleshoot errors in computing the three components of the Flesch readability Index. In addition, they suggest three functions that you should write to support this menu:

sentences( text ), which takes in any string of text and returns the number of sentences present, according to the rules below

Page 27: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 27 of 43

words( text ), which takes in any string of text and returns the number of words present, according to the rules below

syllables( oneword ), which takes in one word of text, called oneword and returns the number of syllables present, according to the rules below

You are welcome to write additional helper functions, as well!

Punctuation, whitespace, and some functions to get you started

The input text to options 1, 2, and 4 in the readability menu may be any string at all. Because of this, there need to be some guidelines that define what constitutes a sentence, a word, and a syllable within a word.

We will use the term raw word to represent a space-separated string of characters that, itself, contains no spaces. Python's string objects contain a useful method (function) that can split a string into space-separated raw words: it is called split(). For example,

>>> s = "This is a sentence.">>> s.split()['This', 'is', 'a', 'sentence.']

>>> s = "This is \n a sentence." # \n is a newline>>> print sThis is a sentence.>>> s.split()['This', 'is', 'a', 'sentence.']

Thus split returns a list of raw words, with all whitespace removed.

The following function might be useful -- feel free to copy it to your hw5pr2.py file and use it in order to extract a list of raw words from a string of input text:

def makeListOfWords( text ):""" returns a list of words in the input text """L = text.split()

Page 28: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 28 of 43

return L

Admittedly, you could avoid using this function simply by calling split as needed.

After whitespace, punctuation is a second cue that we will use to define what constitutes a sentence and a word.

The following function will be useful in stripping non-alphabetic characters from raw words - you should also use this in your hw5pr2.py file:

def dePunc( rawword ):""" de-punctuationifies the input string """L = [ c for c in rawword if 'A' <= c <= 'Z' or 'a' <=

c <= 'z' ]# L is now a list of alphabetic charactersword = ''.join(L) # this _strings_ the elements of L

togetherreturn word

Because most of the non-alphabetic characters we need to remove will be punctuation, the function is called dePunc. It uses a list comprehension that creates a list of all and only alphabetic characters (hence the if, which is allowed in list comprehensions). That list L, however is not usable as a string, so the "magic" line word = ''.join(L) converts the list L into a string held by the variable word. That line is really not magic -- join is simply a method of all string objects.

Definition of "a word":

For this problem, we will define a word to be a raw word with all of the non-alphabetic characters removed. For example, if the raw word was one-way, then the corresponding word (with punc. removed) would be oneway. A raw word will never create more than one punctuation-removed word.

However, a raw word could have only non-alphabetic characters. For example, the raw word 42!will disappear entirely when the non-alphabetic characters are removed. We will insist that a word has at

Page 29: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 29 of 43

least one alphabetic character (thus, the empty string is not a word).

Here's an example of dePunc in action:

>>> dePunc( "I<342,don'tYou?" )'IdontYou'

Counting words

So, with these two functions as background, the number of words in a body of text is defined to be the number of non-empty, alphabet-only, space-separated raw words in that text. Using makeListOfWords and dePunc will help to write a function numWords( text ), that takes any string as input and returns the number of words, as defined above, as output.

Here are some examples -- note that this is not an exhaustive list of possibilities! You may want to test some other cases, as well.

>>> words( 'This sentence has 4 words.' )4>>> words( 'This sentence has five words.' )5>>> words( '42 > 3.14159 > 2.71828' )0

Note that these rules have their limitations! The first example probably should be considered to have 5 words, but because it would take a person to disambiguate all of the many possibilities (and different people might disagree!), we will stick with this definition, despite its limitations.

Counting sentences

The rules used for counting sentences within a string are

We will say that a sentence has occurred any time that one of its raw words ends in a period . question mark ? or exclamation point ! Note that this means that a plain period, question mark, or exclamation point counts as a sentence.

Page 30: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 30 of 43

The empty string is the only string that has 0 sentences. Any other string should be considered to have at least one sentence.

Thus, as long as there is at least one sentence in the text, an unpunctuated fragment at the end of the text does not count as an additional sentence. This may seem a bit much, but in fact it means you don't have to create a special case for the last raw word of the text.

Here are some examples -- again, this is not an exhaustive list of possibilities! You may want to test some other cases, as well.

>>> sentences( 'This sentence has 4 words.' )1>>> sentences( 'This sentence has no final punctuation' )1>>> sentences( 'Hi. This sentence has no final punctuation' )1# Note! Fragments don't count unless there are no sentences at all

>>> sentences( 'Wow!?! No way.' )2>>> sentences( 'Wow! ? ! No way.' )4

Counting syllables

You will only need to count syllables in punctuation-stripped words (not raw words with non-alphabetic characters). When writing your code that counts syllables in a word, you should assume:

A vowel is a capital or lowercase a, e, i, o, u, or y.

A syllable occurs in a punctuation-stripped word whenever:

o Rule 1: a vowel is at the start of a word

o Rule 2: a vowel follows a consonant in a word

Page 31: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 31 of 43

o Rule 3: there is one exception: if a lone vowel e or E is at the end of a (punctuation-stripped) word, then that vowel does not count as a syllable.

o Rule 4: finally, everything that is a word must always count as having at least one syllable.

Here are some examples -- this definitely is not an exhaustive list of possibilities! You will want to test some other cases, as well.

>>> syllables( 'syllables' )3>>> syllables( 'one' )1>>> syllables( 'science' ) # it's not always correct...1

As with words and sentences, these rules do not always match the number of syllables that English speakers would agree on. For computing readability, however, the errors tend not to impact the final score too much, since they vary in both directions.

How should the input be collected?

For this problem, use input in order to take in the numeric menu choices from the user.

However, use raw_input to take in the text for options 1, 2, 3, and 4. This way, the user will not have to type quotes. It is possible to paste in large amounts of text at the raw_input prompt -- I tried the entirety of Romeo and Juliet and it worked fine on a PC and Mac, though you may have to hit return an additional time.

Sample readability scores

In addition to the counting capabilities mentioned above, you should also implement the overall Flesch readability index as option #4.

A few details:

Page 32: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 32 of 43

In addition to the overall readability score, be sure to print the number of sentences, words, and total number of syllables in the input text.

Cast the floating-point Flesch readability score to an int.

If the denominator numWords is zero, you should print a warning and continue to provide the readability menu.

Here are two example runs (just option #4):

Choose an option: 4Type some text: The cow is of the bovine ilk; one end is moo, the other milk.

Number of sentences: 1Number of words: 14Number of syllables: 16Readability index: 95

Choose an option: 4Type some text: Fourscore and seven years ago our fathers brought forth on this continent a new nation conceived in Liberty and dedicated to the proposition that all men are created equal.

Number of sentences: 1Number of words: 29Number of syllables: 48Readability index: 37

Computing the readability of one of your papers

Finally, copy-and-paste one of your own papers (or other works) into the readability scorer. Include a comment or triple-quoted string at the TOP of your file that mentions what you tested (you don't need to include all the text, just what text it was) and what it's score was... we look forward to seeing the results!

Page 33: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 33 of 43

If you have gotten to this point, you have completed problem4! You should submit your hw5pr4.py file at the Submission Site.

Problem 5: Matrix Multiplication (hw5pr5.py) [15 extra points; individual or pair] Practice with array manipulation (Difficulty: Medium)

Homework 5, Problem 5: Gaussian Elimination [15 extra points; individual or pair]

Submission: Submit your hw5pr5.py file to the submission server

In this problem you will write a series of functions which, taken together, will implement a linear-equation solver based on a technique called Gaussian Elimination. Gaussian elimination is another name for the process of using row operations in order to bring a matrix to reduced-row-echelon form.

It turns out that this is simply a natural end result from writing a few short functions -- the row operations -- that alter 2d arrays.

Your main function, gauss(), should contain an array named A. Upon startup, the array A should have the following 3x4 default value:

A = [ [2.0,4.0,5.0,34.0], [2.0,7.0,4.0,36.0], [3.0,5.0,4.0,35.0] ]

Please use this default value -- it will be convenient for testing. In addition, one of the menu options will allow the user to change this matrix.

Then, the program should offer the user the following menu:

(1) Enter the size and values of an array (2) Print the array (3) Multiply an array row by a constant (4) Add one row into another (5) Add a multiple of one row to another (6) Solve! (7) Invert! [This is extra...]

Page 34: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 34 of 43

(9) Quit

Which choice would you like?

The bulk of this problem's work lies in implementing the different options on this menu. In doing so, you should implement the following functions:

gauss

gauss() should print out the above menu, handle the user's choice, and loop until the user quits.

enterValues

enterValues() should ask the user for a list of lists that represents a 2d matrix. It will be up to the user to input valid data (and you may assume that we will test your code only on valid inputs). By using input, this method becomes quite straightforward! Be sure to return the matrix that is entered. For example, here the user's input is in blue:

>>> enterValues()>>> Please type/paste a 2d list of lists: [ [1,1,1,6], [0,2,-1,3], [4,0,10,42] ][ [1,1,1,6], [0,2,-1,3], [4,0,10,42] ]

printArray

printArray(A) should take in a 2d array A and print it out. The key line to print a single value neatly formatted is the following:

print "%8.3f " % (A[row][col]) ,

A bit of explanation: this is the formatted printing that was introduced in the relativistic physics-simulation problem a few weeks ago. The string at left is the "format string." It says to use 8 spaces total, 3 of which should be after the decimal point, and the f indicates that it expects a floating-point number. Fortunately, it will take an integer, as well, so there's no need to convert (yet). The % sign indicates that the values to be printed are to follow -- those values to be printed are always in a tuple, which is a read-only list

Page 35: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 35 of 43

that uses parentheses instead of square brackets. Then, the tuple of the current array element appears, followed by a comma, which tells Python not to go to the next line.

That's a lot of stuff in one line of code, but there's no need to worry about it all at once. However, because the above line prints only one element, it will need to be inside a nested for loop, in which the outer loop iterates over the rows and the inner loop iterates over the columns. You'll need a plain print at the appropriate place, in order to place each row on a separate line.

Printing all the time

It's useful to save yourself the trouble of entering menu option #2 each time you would like to see the array. So, in addition to having option #2, you might consider calling printArray just before printing the menu each time through your primary while loop.

multRow

multRow(A, r, m) should multiply all of the elements in row r of the input array A by the value m. It should not change anything else in the array, nor should it ask for inputs -- nor should it print anything. The prompts for input and all output printing should be in the main function, gauss. Also, note that we start counting at 0, with row 0 being the topmost row, row 1 being the next row, and so on. See the complete run, below, for a detailed example on input and output.

addMofRowSIntoRowD

addMofRowSIntoRowD(A, m, rs, rd) should add each element of row rs, multiplied by m, into row rd. As in the prior two helper functions, row rs should remain completely unchanged; row rd will most likely change, and this method should not change anything else, ask for inputs, or print anything.

solve

Page 36: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 36 of 43

The following is a pretty extensive description of how solve should run. At the end of this description is a summary about how you might organize for loops to implement Gaussian Elimination.

solve(A) should use the previous row-operation methods in order to solve the system of equations represented by the 2d array. First, if the number of columns is not exactly one greater than the number of rows, this method should simply print a message and return.

However, when the number of columns is one greater than the number of rows, this method should diagonalize the left-hand side of the array so that every diagonal entry is 1 and every off-diagonal entry is 0. You should use only row operations (the row methods defined above) to do this.

Note that the right-hand column will not, in general consist of zeros and ones -- rather, it will hold the solution to the original set of equations. Here is a sample "before" and "after" array:

Before:

2.000 4.000 5.000 34.000 2.000 7.000 4.000 36.000 3.000 5.000 4.000 35.000

Or, for easy pasting into Python: [ [2.0, 4.0, 5.0, 34.0], [2.0, 7.0, 4.0, 36.0], [3.0, 5.0, 4.0, 35.0] ]

After calling solve:

1.000 0.000 0.000 3.000 0.000 1.000 0.000 2.000-0.000 -0.000 1.000 4.000

Note the negative zeros -- this is not a problem at all.

To make things more concrete, here is a step-by-step example of how solve should work. Basically, solve uses the two methods multRow and addMofRowSIntoRowD repeatedly in order to diagonalize all but the right column of the array:

Page 37: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 37 of 43

Suppose we have three linear equations in three unknowns (the variables x, y, and z):

2x + 4y + 5z = 342x + 7y + 4z = 363x + 5y + 4z = 35

Our goal is to do a series of operations such that the coefficients along the diagonal all end up 1, and all the other coefficients end up 0. When we have reached this configuration, we will be able to read off the values of the variables directly. Obviously, the operations we perform must be such that they do not disturb the meaning of the equations.

Throughout this example, we'll always show all the variables and coefficients, even when the coefficient is 0 or 1, just to make things clear. Also, in each step we'll draw a pointer in front of each equation that has changed since the previous step.

The first step is to divide the zeroth equation by 2, which is the coefficient of x in that equation. That will make the coefficient of x in the zeroth equation 1:

--> 1x + 2y + 2.5z = 172x + 7y + 4z = 363x + 5y + 4z = 35

Now, notice that if we add negative two times the new zeroth equation to the first equation, the coefficient of x in the first equation will become 0. To the same end we add negative three times the zeroth equation to the second equation.

1x + 2y + 2.5z = 17--> 0x + 3y + -1z = 2--> 0x + -1y + -3.5z = -16

Next we repeat the process, dividing the first equation by 3 so that its y coefficient becomes 1:

1x + 2y + 2.5z = 17--> 0x + 1y + -0.33z = 0.66

0x + -1y + -3.5z = -16

Page 38: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 38 of 43

Then we add negative two times the first row to the zeroth row, and we add one first row to the second row. This will get the coefficient of y to be 0 in the zeroth and second equations (notice that since we have zeroed out the coefficients of x in all but the first equation, we won't mess up the x coefficients by doing this):

--> 1x + 0y + 3.16z = 15.660x + 1y + -0.33z = 0.66

--> 0x + 0y + -3.83z = -15.33

Finally, we divide the second equation by -3.83 to get its z coefficient to be 1, and add -3.16 and 0.33 times the result from the zeroth and first equations, respectively, to obtain:

--> 1x + 0y + 0z = 3--> 0x + 1y + 0z = 2--> 0x + 0y + 1z = 4

Thus, the solution of these equations is:

x = 3y = 2z = 4

Now, the thing to notice is that the variables play no role in this process; only the coefficients matter! If we take the variables out, all we are doing to solve a system of 3 equations in 3 unknowns is manipulating a 3 by 4 array of coefficients.

Important Notes:

In general Gaussian Elimination can be tricky as the input may not be well behaved. In particular, you may find that you don't actually have n distinct equations because one may be a linear combination of some of the others. If this happens there is not enough information to solve the system completely, and Gaussian elimination will lead one of the rows of the array to be all zeroes. This in turn will likely lead to a division by zero error. You need not worry about this and related problems. Just implement the naive algorithm; we will only test it on well behaved input.

Page 39: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 39 of 43

Similarly, you may have a well-behaved problem, but such that the rows need swapping (because one of the pivot values is 0). Again, we will not test data for which this happens.

You may find your results include the value -0 in some places where you expect the value 0. This is ok, and is the result of the finite precision of computer arithmetic.

What does all that mean about solve ?

In sum, you will want to run an outer loop over the columns and an inner loop over the rows:

for col in range(len(A)):# do the appropriate thing here

for row in range(len(A)):# do the appropriate thing here when row != col

Extra Credit (up to +5 points):

For optional extra credit of up to +5 points, add another option to the menu:

(7) Inverse!

and when that option is chosen, your program should:

1. Check if the array (matrix) is currently square. That is, if the number of rows equals the number of columns. If not, you should print a warning message and return to the menu -- only square matrices have inverses.

2. If the array is square, you should compute its inverse and replace the current array with its inverse. How? One way to do this is to create an array with the same number of rows and twice as many columns as described at either of these URLs:

o http://www.tutor.ms.unimelb.edu.au/inverse/inverse_basic.html provides a slightly simpler explanation if you're not familiar with matrices, inverses, etc.

Page 40: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 40 of 43

o http://www.richland.cc.il.us/james/lecture/m116/matrices/inverses.html is a bit more complicated, but explains why the technique works.

You can then use the row operations for which you've already created methods in order to find the inverse. Finally, be sure to replace the original matrix with its inverse.

As with the solve method, you can assume that the matrix will have an inverse (it will not be singular or otherwise poorly behaved).

Example run of gauss()

You may want to check that your functions work on the examples within this run:

>>> gauss()

(1) Enter the values in the existing array(2) Print the array(3) Multiply an array row(4) Add one row into another(5) Add a multiple of one row to another(6) Solve!(7) Invert! [This is extra credit](9) Quit

Choose one: 2

The array is now

2.000 4.000 5.000 34.000 2.000 7.000 4.000 36.000 3.000 5.000 4.000 35.000

(1) Enter the values in the existing array(2) Print the array(3) Multiply an array row(4) Add one row into another(5) Add a multiple of one row to another(6) Solve!(7) Invert! [This is extra credit](9) Quit

Page 41: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 41 of 43

Choose one: 3Which row? 0What multiple? 2

The array is now

4.000 8.000 10.000 68.000 2.000 7.000 4.000 36.000 3.000 5.000 4.000 35.000

[[ MENU ]]

Choose one: 4Which is the source (unchanged) row? 2Which is the destination (changed) row? 1

The array is now

4.000 8.000 10.000 68.000 5.000 12.000 8.000 71.000 3.000 5.000 4.000 35.000

[[ MENU ]]

Choose one: 5Which is the source (unchanged) row? 1What multiple of that row? 0.5Which is the destination (changed) row? 2

The array is now

4.000 8.000 10.000 68.000 5.000 12.000 8.000 71.000 5.500 11.000 8.000 70.500

[[ MENU ]]

Choose one: 6

Page 42: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 42 of 43

The array is now

1.000 0.000 0.000 3.000 0.000 1.000 0.000 2.000 -0.000 -0.000 1.000 4.000

[[ MENU ]]

Choose one: 1Type or paste a 2d matrix: [ [ 3,5,0 ], [ 1,2,1 ], [ -1,1,7 ] ]

The array is now

The array is now

3.000 5.000 0.000 1.000 2.000 1.000 -1.000 1.000 7.000

[[ MENU ]]

Choose one: 7

The array is now

-13.000 35.000 -5.000 8.000 -21.000 3.000 -3.000 8.000 -1.000

[[ MENU ]]

Choose one: 9

If you have gotten to this point, you have completed problem5! You should submit your hw5pr5.py file at the Submission Site.

Page 43: Research Ideas - Northwestern Universitycs.northwestern.edu/~akuzma/classes/EECS110-s09/hw/hw5/... · Web viewBe sure to set every value of newB (the new data), whether or not it

Page 43 of 43