CSCI 141 - Assignment 3

Scott Wehrwein

Winter 2023

In this assignment, you’ll complete three programs. The first calculates Fibonacci numbers to approximate the golden ratio, the second prints a particularly organized grid of numbers called a circulant matrix, and the final one is a guessing game.

Collaboration and Academic Honesty

The programs you write solution MUST be authored solely by you. You may not view or copy anyone else’s code, or have another person tell you what to type. You can discuss the problems with your peers, but these discussions should happen with Thonny (or your IDE of choice) closed, and you should take a break before returning to write code to ensure that you truly understand your answers. Please see the academic honesty policy on the syllabus for more details, and if you have any questions, or are unsure about whether a specific sort of collaboration violates academic honesty, please come talk to me.

1. Fibonacci Numbers and the Golden Ratio

The Fibonacci sequence is an interesting mathematical curiosity. The beginning of the sequence looks like this:

\(f_0\) \(f_1\) \(f_2\) \(f_3\) \(f_4\) \(f_5\) \(f_6\) \(f_7\)
0 1 1 2 3 5 8 13

You might be able to spot the pattern: after the first two terms are given (0 and 1), the next term in the sequence is always the sum of the prior two terms.

The Fibonacci sequence is simple to define and not too hard to compute, but it has some surprisingly deep mathematical properties. The Fibonacci sequence and related concepts show up in patterns in nature all the time (try searching the internet for “Fibonacci in nature” for some examples). It also has some practical applications in computer science.

One interesting property of the sequence is that the ratio between each pair of terms in the sequence (i.e., \(f_n / f_{n-1}\)) converges to the golden ratio, which is often written using the Greek letter \(\phi\) (“phi”). The value of this constant is roughly \(1.61803398875\), although the digits keep going forever. The golden ratio is frequently used in design and art, and also has interesting mathematical properties and applications.

Write a program that takes a single integer command line argument, \(n\), prints \(f_n\), the \(n\)th Fibonacci number, then prints an estimate of the golden ratio computed using \(f_n\) and \(f_{n-1}\). Notice that because the terms are numbered starting at zero, \(f_3\) is actually the fourth number in the sequence, so be careful to get the correct one.

Since your program needs two numbers to estimate the golden ratio, the smalleset valid input for \(n\) is 1. You are not required to check for bad user input where \(n <= 0\). When \(n\) is 1, the golden ratio calculation is \(1/0\), so your program should print “infinity” for the golden ratio estimate when \(n=1\).

Here are a few sample outputs: Sample runs of fib.py

Testing

At this point you should know enough to test this program thoroughly. You are responsible for making sure it works for all valid inputs.

2. Circulant Matrices

A circulant matrix is an n \(\times\) n grid of numbers in which each row has the same numbers, but shifted right by one spot, with numbers wrapping around from the end to the beginning as they fall off the end of a row. For example, a circulant matrix whose first row is 1 2 3 would have the next row 3 1 2: everything shifts right one column, and the 3 wraps back to the first column. This has the consequence that each number occurs exactly once in each row and exactly once in each column1. Another way to look at it is that each of the diagonals of the matrix has the same number repeated. For example, here are two possible \(4\times4\) circulant matrices:

             0 1 2 3         2 3 0 1
             3 0 1 2         1 2 3 0
             2 3 0 1         0 1 2 3
             1 2 3 0         3 0 1 2

Your program should take two command line arguments. The first argument is an integer specifying the side length of the matrix. The second one is the top-left number of the square, which should be an integer between 0 and one less than the side length. If the second argument is not in this range, your program should print a message saying so and terminate. Your program will then print a circulant matrix in which each of the rows has the numbers from 0 to the side length - 1.

Here are some sample outputs:

Sample runs of circ.py
Sample runs of circ.py

Tips and Tricks

There are many ways to solve this, some simpler than others. If you’re having a lot of trouble, step back and think about whether you can change your design to make the code easier to write. A few specific suggestions:

Testing

At this point you should know enough to test this program thoroughly. You are responsible for making sure it works for all valid inputs.

3. Guessing Game

Suppose you are a computer programmer working for a company, called NostalgiaSoft, that makes old-style, text-only games for people who remember using computers back in the early 1980s. The game you have been tasked to write is a simple guessing game. The program is run with a command line argument specifying how many guesses the player is allowed, and the player is given that many chances to guessing a secret two-character sequence. Because the game is to be marketed to alumni of Western Washington University, the letters are selected from the letters in the word bellingham.

Several examples of the gameplay are shown here: Sample runs of guessing_game.py Sample run of guessing_game.py

Game Modes

To satisfy the strict guessing-game industry regulations, the game must be able to run in two modes: DEBUG mode and PLAYER mode. In DEBUG mode, the user can set the secret letters with a command line argument. In PLAYER mode, the secret letters are chosen randomly by the program. Otherwise, the program’s behavior is the same in both modes.

Command Line Arguments

To run in PLAYER mode, the program takes two command line arguments. To run in DEBUG mode, the program takes four command line arguments.

Guesses. In both modes, the first argument is an integer specifying the number of guesses the player is allowed. You may assume this number is nonnegative, but your program should be able to handle any integer number of guesses 0 or larger.

Game Mode. The second argument determines the game mode:

You can assume the user has entered the arguments correctly for one of the two game modes.

Specification

Your manager has provided you with the following specification that outlines the program’s behavior:

  1. The program prints a brief blurb that explains the game to the user.

  2. If the game is in PLAYER mode, the program randomly chooses two secret letters from among the letters of the word bellingham. Because the letters are chosen independently, both the first and second secret letters might be the same. If the game is in DEBUG mode, the secret letters are the ones supplied in the third and fourth command line arguments.

  3. Next, the guessing phase of the program begins. While the player still has guesses remaining (the initial number of guesses is given by the first command line argument), the game prompts the user to guess a letter.

  4. For each of the two secret letters that has not already been correctly identified in a prior guess, the program prints a message stating whether the guess was correct or not. Notice that once a letter has been guessed correctly, output for subsequent guesses should not mention that letter. The user may guess the letters in any order (i.e., they do not need to guess the first letter correctly before guessing the second letter).

  5. If the player has successfully guessed both letters, the program prints “You win” and terminates right away, even if the player has guesses remaining.

  6. If the player has not exhausted their number of guesses, go back to step 3 (prompt for another guess).

  7. If the player runs out of guesses before guessing both letters correctly, the program prints a message that tells the player they’ve run out of guesses and reveals the correct secret letters.

Write your program in a file called guessing_game.py. This game can be implemented many different ways. Declare and use as many variables as you need to keep track of guesses and secret letters. The logic for a sample losing game play is shown below.

Testing

The advantage of implementing DEBUG mode is that it makes testing a lot easier–you can choose the secret letters carefully to test the various possible outcomes. In particular, you should be sure to test all combinations of guessing patterns and secret letter scenarios. Here’s a non-comprehensive list of things to consider, just to get you started:

Submission

Make sure your programs are thoroughly tested, check over the rubric, and upload fib.py, circulant.py, and guessing_game.py to Canvas. Fill out the A3 Survey on Canvas with the number of hours you spent on this assignment.

Rubric

This assignment is graded out of a total of 54 points.

Style Points (6 points)

fib.py (10 points)

circulant.py (10 points)

guessing_game.py (28 points)

Challenge Problem

This challenge problem is worth up to two points of extra credit. Write a program that takes a single non-negative decimal integer as a command line argument, then prints the binary representation of the number with no leading zeros.

Submit your Challenge Problem solution in a file named binary.py.


  1. You’re unlikely to find help there if you’re struggling with this problem, but if you’re curious to learn more about circulant matrices check out the Wikipedia article. I’ve asked you to produce a specific case of circulant matrices where the values in each row are the sequential numbers from 0 to n-1, but to be considered circulant, a matrix can have any values as long as its rows have the shifted-and-wrapped structure.↩︎