Let's look again at a typical (now quite easy) programming problem.
Problem : Primes. In this little problem example, you are asked to write a program that can determine whether a given integer is a prime number. Remember: a prime number is a natural number $p \geq 2$ that has only trivial divisors, namely 1 and itself. There is no need to implement sophisticated algorithms like the Rabin-Miller test. Input numbers will be quite small.
Input: several lines, the $i$-th line containing a single integer $n_i$ with $-1,000,000 \leq n_i \leq 1,000,000$.
Output: one output line per input line, the $i$th output line being "$n_i$ is prime" "$n_i$ is not prime", depending on whether the $n_i$ was prime or not.
11 21 31 41 51 61 71
11 is prime 21 is not prime 31 is prime 41 is prime 51 is not prime 61 is prime 71 is prime
For each such problem please create a directory on your computer. Create a sub-directory testcases.
Exercise In the sub-directory testcases, create two files: sample.in and sample.ans. Copy the above test input into sample.in and the test output into sample.out.
Exercise Create two more files: edge-cases.in and edge-cases.ans. Fill them with what you think are edge cases that you would like to test.
Writing your program
Now comes the most important part: implementing your solution. For this problem, this is not too hard to do. You can see my code here:
def isPrime(n):i = 2while (i*i <= n):if n % i == 0:return Falsei = i+1return Truewhile True:try:line = input()except EOFError:breakn = int(line)if isPrime(n):print (n, "is prime")else:print (n, "is not prime")
Have a look at how we read from standard input (the console) in python. We have to use try/except to handle the end of the input.
Testing your program
Suppose you have written a program primes.py. You can now test it by hand by running it on the terminal:
python primes.py55 is prime9191 is not prime
The blue text is, for clarity, the output of the program; the black test is what the user (i.e., you or I) entered. In the long run, we don't want to enter the test input by hand. Fortunately, there is the <-operator on the console:
python primes.py < testcases/sample.in11 is prime 21 is not prime 31 is prime 41 is prime 51 is not prime 61 is prime 71 is prime
The operator < opens the file testcases/sample.in and feeds its content as standard input to the program python primes.py. The output is still printed on the console. We now want to compare the output of our program to the "correct" output in testcases/sample.ans. This can be done with the shell command diff:
python primes.py < testcases/sample.in > output.txt
The operator > re-directs the standard output into the file output.txt; if the latter does not exist yet, it will be created. Now we can use diff to check whether the two files output.txt and testcases/sample.ans differ:
diff -b output.txt testcases/sample.ans
The command diff produces no output. This is good: it means that it has not found any differences between the two files.
We can go one step further and do away with the temporary output file output.txt. Instead, we use the shell pipe operator | to direct the output of our program into the standard input of diff:
python primes.py < testcases/sample.in | diff -b testcases/sample.ans -
Automated Testing
This still becomes very tiresome if we have for example ten different test files. For this, I wrote a shell script that facilitates automated testing. For this to work, your test input / test output files must match in name, i.e., be named like file-XYZ.in and file.XYZ.ans.
Download it and try to get it to run. If you use C or C++ instead of python, the compiler will produce an executable. In this cases, use the bash script
instead.
icpc-run-python primes.py testcases/*.inrunning program primes.py testcases/edge-cases.in Failure testcases/sample.in Success
As you can see, my program failed at testcases-edge.cases.in, and in fact, my implementation above is not completely correct.