The Basel Problem

A famous problem in the early 1700s concerned the sum of the squares of the reciprocals of the integers.  Namely what is 1/(1*1) + 1/(2*2) + 1/(3*3) ....  If you add up all of these numbers (yes, to infinity) you'll actually get a sum that's about 1.645.  You can try that on your calculator, or, wait a sec, you have Python!  This was called the Basel Problem -- read at least a little about it.  It made my favorite mathematician, Leonhard Euler, famous when he was just 28.  He found that this sum eventually becomes equal to pi*pi/6.  This was a great result in mathematical analysis, and the world's most famous unsolved problem (The Riemann Hypothesis) is related to it.  I used to show his beautiful solution of this problem to my Intel Math Research class (now Regeneron) many years ago.

For this assignment, you're going to be creating a program, in stages.  After you finish stage 1, you'll modify the program to handle Stage 2, etc.  And you'll submit the program file that solves the last Stage that you are able to solve to the homework server.  In the Comments-to-Teacher, indicate which stages you've correctly solved.


Remember what we covered in class about the sys library:  If you import the sys library, and look at the variable sys.argv -- it will give you a list of all of the words (as strings) on the command-line when this program was run (except for the word, "python"). So the following code inside a file called fred.py will display that list of words:

import sys
print(sys.argv)

So, if you execute fred.py on the command-line as follows, it will print the second line:

C:/temp> python fred.py hi 4 5 folks
['fred.py', 'hi', '4', '5', 'folks']


Stage 1: create the basel.py program that will take one positive integer argument on the command-line and add up the reciprocals of the squares of all numbers from 1 to that positive integer, and print out 1) that positive integer, 2) the sum,  3) the value of pi*pi/6, and 4) the difference between them.  If you are given the value 2 as the command-line argument, you'll add up 1/(1*1) + 1/(2*2), which is equal to 1 + .25 = 1.25.  You can get the value of pi by importing the math library, and its value is math.pi.  So...example:

C:/temp> python basel.py 2
2 1.25 1.6449340668482264 0.3949340668482264

Of course, your program should be able to handle any (reasonable) positive integer.  Don't get too crazy.  But take a look at the difference and watch it diminish as you try larger and larger numbers.


Stage 2: you're still working with basel.py, but you'll need to modify it.  Instead of just one positive argument on the command-line, you can have as many as the user wants to type.  So if you execute:

c:/temp> python basel.py 2 5 17
2 1.25 1.6449340668482264 0.3949340668482264
5 1.4636111111111112 1.6449340668482264 0.1813229557371152
17 1.587806741057444 1.6449340668482264 0.0571273257907825

However, in addition, you will need to first check all the values on the command-line that you received and if there is a problem anywhere, then print out how to use this program instead.  For instance, if the user doesn't give you any numbers at all, or if any one of the arguments is not a positive integer, then don't print out any values, just print out something like:

c:/temp> python basel.py 3 18 fred 9
Correct usage: python basel.py num [num ...]
Must have one or more positive integers

There's a string method called s.isdigit() that will return True if the string in the variable s is a non-negative integer, and False otherwise.  For instance: "34".isdigit() returns True but "-6".isdigit() returns False, and "f5".isdigit() also returns False.  Basically, this method simply checks if that every character in the string is a digit.


Stage 3: In this stage, you'll modify the program to accommodate another argument: the name of a file to write your results to.  It will be the first command-line argument.  So, instead of printing out your results, you'll write them to the requested file.

 This will take some more work, because you'll have to create each output line as a string (you may not use the print() function for writing to the file). So far, you have been using the int() function to convert a string into a number.  Once you've calculated the numbers, you'll need to convert numbers back into strings, which can be done with the str() function.  So, for instance str(math.pi) produces the string '3.141592653589793'. Build up each output line as a string from the 4 numbers that it should contain, and then write it out using f.write(), and remember the '\n'.

c:/temp> python basel.py fred.txt 2 5 17
c:/temp> type fred.txt
2 1.25 1.6449340668482264 0.3949340668482264
5 1.4636111111111112 1.6449340668482264 0.1813229557371152
17 1.587806741057444 1.6449340668482264 0.0571273257907825

However, if there's any problem, print out a "Correct usage" message, including if you cannot write to the requested file.


Stage 4: (finally...)  You'll have the same calling sequence: a filename followed by any number of positive integers.  However, you'll write the HTML of a webpage into the requested file, instead of just ordinary text.  You'll be outputting a title as well as a table of values.  For instance:

c:/temp> python basel.py BaseProblemTable.html 2 5 17

Should produce a file called BaselProblemTable.html which looks like a normal web page.  Take a look at the "view source" to see the HTML code your Python program will need to create and write to the file.


Submit your basel.py file to the homework server.  In the Comments-to-Teacher, indicate which stages you've correctly solved.