CS303E Project 2

Instructor: Dr. Bill Young
New Due Date: Wednesday, April 9, 2025 at 11:59pm

Copyright © William D. Young. All rights reserved.

Note the new due date: Wednesday, 4/9.

The Fibonacci Numbers

Some of the following information is copied from Wikipedia: Though named after Leonardo of Pisa, also known as Fibonacci, these numbers were first described in Indian mathematics as early as 200 BCE in work by Pingala on enumerating possible patterns of Sanskrit poetry formed from syllables of two lengths. Fibonacci introduced the sequence to Western European mathematics in his 1202 book Liber Abaci.

The Fibonacci sequence (where F(i) is the ith element of the sequence) is defined by the following equations:

  F(0) = 0
  F(1) = 1
  F(n) = F(n-2) + F(n-1), for n > 1
That is, each successive Fibonacci number is the sum of the previous two. Thus, the first 20 terms of the sequence as a list are:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
What's the next one?

Fibonacci numbers appear unexpectedly often in mathematics, so much so that there is an entire journal dedicated to their study, the Fibonacci Quarterly. They appear in biological settings, such as branching in trees, the arrangement of leaves on a stem, the fruit sprouts of a pineapple, the flowering of an artichoke, an uncurling fern, the arrangement of a pine cone's bracts, and the patterns in a sunflower (see picture above).

We will be encountering Fibonacci numbers again later in the semester in slideset 12. The defining equations lead to a very simple, but horribly inefficient recursive definition in Python. But, it's pretty simple to define a straightforward and much more efficient iterative implementation of the Fibonacci sequence in Python using a loop. Here's a function that creates a list of the first n Fibonacci numbers.

def firstNFibNumbers (n):
    """ Return a list of the first n Fibonacci numbers. If 
        n <= 0, return the empty list. """
    
    if n <= 0:
        return []

    # Handle the cases of n == 1 and n == 2 specially.
    elif n == 1:
        return [ 0 ]
    elif n == 2:
        return [ 0, 1 ]

    # Here we know that n is at least 2.
    else:

        # Initialize fib1 and fib2 with the first 
        # two Fibonacci numbers.
        fib1, fib2 = 0, 1

        # Initialize our list of Fibonacci numbers
        # found so far.
        fibs = [ 0, 1 ]

        # To generate the next n-2 Fibonacci numbers, use the 
        # previous two values to generate the next value.
        for counter in range( 2, n ):

            # Update fib1 and fib2 with their new
            # values.
            fib1, fib2 = fib2, fib1 + fib2

            # Add the newest value to the list we're
            # creating.
            fibs.append( fib2 )

        # Return the list. 
        return fibs
You're advised to study this function very carefully to see how it works, because you will be using it and writing several similar functions in this project.

Your Assignment:

Your assignment is to build an application that allows the user to select from a variety of actions, including: generate a list of the first N Fibonacci numbers (the function above), find and display the nth Fibonacci number, and generate a list of Fibonacci numbers up to and possibly including the positive integer N. Your program will print out an initial welcome message and a list of available commands. There are 6 possible commands, which will be entered as a numeral between 0 and 5 (remember that it comes in as a string). Here are the available commands:
  0: Exit.
  1: List the first N Fibonacci numbers.
  2: Display the nth Fibonacci number (0-based).
  3: List the Fibonacci numbers less or equal to N.
  4: How many Fibonacci numbers are less or equal to N?
  5: Display this help message. 
Depending on the command, you should ask the user to specify the parameter (N or n). You will then compute and print the answer, print an error message and the menu, or print a goodbye message and exit. You must validate the inputs. Don't assume that the user inputs integers or that they're in the right ranges. If they're not, you'll print an error message. Note that the error message for entering an incorrect command is different than the one for incorrect data under a command. Entering an incorrect command also causes printing the help message. See the samples below.

Also, note that above I supplied for you the function firstNFibNumbers, which computes the first n Fibonacci numbers. But what do you do if the input is negative? In the function above, I decided to return the empty list. However, a caller can either make use of the behavior supplied by that function, or do additional validation of the parameter before the function is called. That's what you need to do in this project. Notice from the expected output below that the driver (top level function) validates the parameter, prints an error message, and doesn't call the function. That's a very common pattern in programming. Division will fail if the divisor is zero; but the smart programmer won't ever call the division function in such a case.

BTW: The first few Fibonacci numbers are [0, 1, 1, 2, 3, 5, 8]. So, when you're solving tasks 3 or 4, you should count 1 twice. If asked (task 3) to list the Fibonacci numbers less than or equal to 1, the answer is [0, 1, 1], and (task 4) there are 3 of them. Note that this was simply a design choice; we could have made a different choice.

Expected Output:

Below is some sample output for this program. You should match this exactly for the given inputs.

> python Project2.py

Welcome to the Fibonacci Number laboratory!

The following commands are available:
  0: Exit.
  1: List the first N Fibonacci numbers.
  2: Display the nth Fibonacci number (0-based).
  3: List the Fibonacci numbers less or equal to N.
  4: How many Fibonacci numbers are less or equal to N?
  5: Display this help message. 

Please enter a command (0, 1, 2, 3, 4, or 5): -10
ERROR: Illegal command. Try again.

The following commands are available:
  0: Exit.
  1: List the first N Fibonacci numbers.
  2: Display the nth Fibonacci number (0-based).
  3: List the Fibonacci numbers less or equal to N.
  4: How many Fibonacci numbers are less or equal to N?
  5: Display this help message. 

Please enter a command (0, 1, 2, 3, 4, or 5): three
ERROR: Illegal command. Try again.

The following commands are available:
  0: Exit.
  1: List the first N Fibonacci numbers.
  2: Display the nth Fibonacci number (0-based).
  3: List the Fibonacci numbers less or equal to N.
  4: How many Fibonacci numbers are less or equal to N?
  5: Display this help message. 

Please enter a command (0, 1, 2, 3, 4, or 5): 0

Thanks for using the Fibonacci Laboratory!  Goodbye.

> python Project2.py

Welcome to the Fibonacci Number laboratory!

The following commands are available:
  0: Exit.
  1: List the first N Fibonacci numbers.
  2: Display the nth Fibonacci number (0-based).
  3: List the Fibonacci numbers less or equal to N.
  4: How many Fibonacci numbers are less or equal to N?
  5: Display this help message. 

Please enter a command (0, 1, 2, 3, 4, or 5): 1
You've asked for the first N Fibonacci numbers. What is N? 0
[]

Please enter a command (0, 1, 2, 3, 4, or 5): 2
You've asked for the nth Fibonacci number. What is n? 0
0

Please enter a command (0, 1, 2, 3, 4, or 5): 3
You've asked for the Fibonacci numbers less than or equal to N. What is N? 0
[0]

Please enter a command (0, 1, 2, 3, 4, or 5): 1
You've asked for the first N Fibonacci numbers. What is N? abc
ERROR: Illegal value entered.

Please enter a command (0, 1, 2, 3, 4, or 5): 1
You've asked for the first N Fibonacci numbers. What is N? -12
ERROR: Illegal value entered.

Please enter a command (0, 1, 2, 3, 4, or 5): 1
You've asked for the first N Fibonacci numbers. What is N? 25
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368]

Please enter a command (0, 1, 2, 3, 4, or 5): 2
You've asked for the nth Fibonacci number. What is n? 17
1597

Please enter a command (0, 1, 2, 3, 4, or 5): 2
You've asked for the nth Fibonacci number. What is n? -4
ERROR: Illegal value entered.

Please enter a command (0, 1, 2, 3, 4, or 5): 3
You've asked for the Fibonacci numbers less than or equal to N. What is N? 1000
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987]

Please enter a command (0, 1, 2, 3, 4, or 5): 3
You've asked for the Fibonacci numbers less than or equal to N. What is N? -10
ERROR: Illegal value entered.

Please enter a command (0, 1, 2, 3, 4, or 5): 4
You've asked how many Fibonacci numbers are less than or equal to N. What is N? abc
ERROR: Illegal value entered.

Please enter a command (0, 1, 2, 3, 4, or 5): 4
You've asked how many Fibonacci numbers are less than or equal to N. What is N? 50000
25

Please enter a command (0, 1, 2, 3, 4, or 5): 5
The following commands are available:
  0: Exit.
  1: List the first N Fibonacci numbers.
  2: Display the nth Fibonacci number (0-based).
  3: List the Fibonacci numbers less or equal to N.
  4: How many Fibonacci numbers are less or equal to N?
  5: Display this help message. 

Please enter a command (0, 1, 2, 3, 4, or 5): ?
The following commands are available:
  0: Exit.
  1: List the first N Fibonacci numbers.
  2: Display the nth Fibonacci number (0-based).
  3: List the Fibonacci numbers less or equal to N.
  4: How many Fibonacci numbers are less or equal to N?
  5: Display this help message. 

Please enter a command (0, 1, 2, 3, 4, or 5): exit

Thanks for using the Fibonacci Laboratory!  Goodbye.

>
Just for fun, ask it to generate the 1000th Fibonacci number and see what happens. Now try the 10000th and the 100000th. The millionth will probably take too long.

Turning in the Assignment:

The program should be in a file named Project2.py. Submit the file via Canvas before the deadline shown at the top of this page. Submit it to the assignment project2 under the assignments sections by uploading your Python file. Make sure that you following good coding style and use comments.

Your file must compile and run before submission. It must also contain a header with the following format:

# Assignment: Project2
# File: Project2.py
# Student: 
# UT EID:
# Course Name: CS303E
# 
# Date: 
# Description of Program: 

Programming Tips:

Add robustness: I always find it a good idea to make any system I code as robust and user-friendly as possible. For example, in my code, I accepted "?" and "help" as alternatives to "5", and "exit" and "quit" as alternatives to "0", under the assumption that a user who hasn't printed the command list lately may have forgotten how to display the menu or leave the system. I figure why not make things as easy as possible for the user? I wouldn't typically advertise such functionality in the help message since it's not part of the "official" interface. It's just there to make the system more user-friendly. You can do this if you want to or not. You certainly won't be penalized if you don't.

Where to Handle Errors: It's also a good idea to make your code as robust as possible. Production code really shouldn't ever crash if a user enters bad input. In a menu-driven system like the one you're programming in this assignment, you'll typically receive input from the user and then call a particular subsidiary function based on that input. But what if the user enters bad input? Where do you handle that?

  1. Where the input is initially received: This is usually best. You'll never call the subsidiary function with erroneous input, so it can be more concise. This assumes that subsidiary functions are always called only in this context.
  2. In the subsidiary functions: This requires potentially redundant error handling by each function. But it ensures that the subsidiary functions are more robust if there's a possibility you'll reuse them in other contexts.

For those commands that ask for extra inputs, I used code like the following within my main loop:

    nString = input("You've asked for the first N Fibonacci numbers. What is N? ")
    if nString.isdigit():
       n = int( nString )
    else:
       print( ERRORMESSAGE )
       continue