Goals
- Introduction to the Environment we will use in CIS 2400: UNIX Terminal and Docker.
- Introduction to C code and exposure to some aspects of C
- including libraries
- forward declarations
- basic printing and command line argument parsing
Collaboration
For assignments in CIS 2400, you will complete each of them on your own. However, you may discuss high-level ideas with other students, but any viewing, sharing, copying, or dictating of code is forbidden. If you are worried about whether something violates academic integrity, please post on Ed or contact the instructor(s).
Setup
Task 1. Setup your docker to gain access to a development environment for the course.
If you haven’t already, you need to follow the Docker Setup. We recommend you try and figure this out ASAP.
Once you have the docker container setup, that is all that is a necessity, however we will give some suggestions on how to use the environment here:
Intro to the Terminal and Shell
One of the goals of this course is to get you experience with the shell. We will cover some basics in class and here, but there is simply too much to talk about in the course. Most people learn the basics of a shell in school and slowly learn more as needed, but if you want to learn more we recommend two things:
- There is a mini course occasionally taught here under the name CIS 1911: Using and Understanding Unix and Linux
- Chapter 17.1 of Dive into Systems: Using Unix
Most computers have some sort of a “Terminal” application that runs a program called a “shell”. The “shell” is a program that prompts the user for a command, runs the command, prints any output and then repeats by asking the user for another command. This makes a shell effectively a REPL (Read Eval Print Loop), but it also supports a lot more features.
A shell’s main job is to provide an interface for users to the system they are interacting with. For us this primarily involves:
- Managing and navigating the filesystem (organizing files, directories, etc.)
- Running existing programs on the system (ones we write, annd already existing ones like the compiler)
Shell programs are somewhat dependent on the system they are implemented for, but this means shell programs for the same system (e.g. bash
, zsh
, fish
, etc.) have a lot in common.
This course uses the shell bash
and many of what you learn in bash
can be applied to shells used in other UNIX-like systems (UNIX-like systems are pretty much everything that is not Windows).
bash
is one of the most popular shells in existence and getting familiar with it (and thus other UNIX-shells) is very beneifical for most who do any programming.
When you open the shell, you should see something like this:
root@dbd8f45192c1:~/workspace#
This is the prompt that gets printed to let you know you can type in a command for the shell to execute.
There are a couple parts to this line, lets break this down.
-
root
: Before the@
identifies the username of the current user (you). You are probably logged into the docker container asroot
-
dbd8f45192c1
: This part is after the@
and before the:
. This part also probably looks different for you and is the “name” for the system the shell is runninng in. -
~/workspace
: This part that comes after the:
identifies the current directory you are in.~
is the “home” directory that is the home of a user. In this example we are in theworkspace
directory and the/
indicates thatworkspace
is within the~
directory.
The last bullet point from above is particularly important. The shell has a “Current Directory” similar to how File Explorer or Finder has a notion of “Current Directory” where those programs need to go in and out of directories to see different files. What this means is that when you are interacting with the shell, there is always a directory you are “in” and you can change what directory you are in to interact with different files.
With this information, we are able to start using the shell to create our files for the homework.
Setting up our files
We recommend you organize your work into separate folders. Suggested names for this assignment’s folder are intro
, setup
or hw00
.
To create a folder (also called a directory) you should just be able to type the following command into the terminal:
mkdir intro
mkdir
is a command to “make a directory” and in the example above we are using it to create a directory called “intro”.
from here we can use the command cd
to “Change Directory” to move our current directory into the newly created one:
cd intro
Note that after you do this, your shell prompt will look different. It will probably look something like:
root@dbd8f45192c1:~/workspace/intro#
Note that the path in the prompt changed to include the directory we are now in. If we now create any files, they will show up in this directory.
For this assignment, we will only need to create and submit two files. approx.c
and compile_command.txt
.
To create a file in the shell we can run the following command:
touch approx.c
touch
creates a file of the specified name if it does not already exist. Note that it does not create directories, that is what mkdir
is for.
From here, you should run a similar command to create the other file needed for this assignment compile_command.txt
From here we can use another command ls
which “Lists” the contents of the current directory.
ls
You should see the files that you have created with the touch
command. If you did everything properly, you should see something similar to the image below. If something went wrong, see further below whwere we talk about the mv
command.
This command only gies us information and does not change anything in the system, but is one of the most commonly used commands. It helps to do run ls
to remind you of what else is in the directory you are currently working in.
From here you can start working the assignment by opening the files we just created with vim
, VSCode or another editor if you have one you prefer.
More Basic Shell Commands (Optional)
If you want to rename a file (because you accidentally spelt it wrong) or you want to move it to another directory, you can use the mv
command which stands for ““Move”.
For example, if I wanted to rename the file example.txt
to renamed.txt
(assuming that example.txt
already exists) then I could type:
mv example.txt renamed.txt
Similar to the mv
command there is the cp
command for “Copying” a file. If I wanted to make a copy of a file I would do:
If I wanted to rename example.txt
to copied_example.txt
, I would do:
cp example.txt copied_example.txt
Lastly, we should let you know about .
and ..
(referred to as “dot” and “dot dot” in lecture). These two are “special” names that change based off of which directoy you are currently in.
.
(dot) refers to the current directory, so the following two names refer to the same file: ./hello.txt
and hello.txt
.
..
(dot dot) refers to the directory that is “above” or the “parent” of the current directory (The current directory is held within its “parent” directory). This can be used to leave a directory that we have entered. For example, if i have a directory called: intro
, I can run: cd intro
to enter that directory and later type cd ..
to leave it and go “up” a level in the directory layout.
For another example, lets say I am in a directory called “example” that has the file blah.txt
. I can refer to that file with ../example/blah.txt
./blah.txt
or blah.txt
and all three would be the same.
More information on the shell that is likely to be useful:
Lastly, we have a quick reference on some information you may find useful when using the terminal. Feel free to come back to it at any time: bash-reference
Instructions
Once you have followed the setup instructions, you should have a folder that contains the files for this assignment: approx.c
and compile_command.txt
.
Required Knowledge
This homework has you writing a little bit of C code from scratch. For now this should be very similiar to code you would write in Java, but with only a few minor differences. The differences you need to know should have been covered in the first lecture or two. These being:
- how to
#include
libraries needed - functions requiring forward declarations
- “strings” in C
- how to compile and run a C program
- how to handle command line args in C.
C doesn’t provide variables with a default initial value like Java does. When you declare a new variable be sure that you assign it a value.
For this assignment, you will be writing a program that takes in a single command line argument (other than the program name) that represents an integer value. This integer value will be used to tell us how many iterations we should use to estimate a the value of pi.
Overview
Despite how the problem looks, you do not need to understand how this mathematical formula works. You only need to replicate it, so no math knowledge is really expected on your end.
There are many ways to come up with an estimate of PI, but we will use the following infinite series:
\[2\sum_{k=0}^\infty \frac{k!\,(2k)!\,(25k-3)}{(3k)!\,2^{k}}=\pi\]If we expand this seires, we get something that looks like:
\[2 * ( \frac{0! * 0! * (0 - 3)}{ 0! * 2^{0}} + \frac{1! * 2! * (25 - 3)}{ 3! * 2^{1}} + \frac{2! * 4! * (50 - 3)}{ 6! * 2^{2}} + ... )\]If we break this down, we get:
- So the first term
(0! * 0! * (0 - 3)) / (0! * 2^0)
- The second term
(1! * 2! * (25 - 3)) / (3! * 2^1)
- The third term
(2! * 4! * (50 - 3)) / (6! * 2^2)
Your task is to write a C program that calculates an approximation of Pi following this formula by adding the terms 0 through N of the series explained above. N will be an integer provided by the user of the program as a command line argument.
Your code should compile to a program called approx
. We have also provided an example of how a user would run your program and the expected output of the program (you should match this output):
root@dbd8f45192c1:~/workspace/intro# ./approx 2
Our approximation of pi to the 2 term is: 2.89999999999999946709294817992486059665679931640625
root@dbd8f45192c1:~/workspace/intro#
Your solution should use the double
type for these calculations and perform them left to right. If you use other floating point types (such as float
) or perform the operations in a different order, then you may get a different result from your calculation than what we have here. Why this may happen is briefly covered in this class, but it is not the point of this assignment. Just use double
and be careful how you calculate your answer.
Other requirements:
- Your program should compile without warning or error. We won’t give you the compilation command, but you should follow what we have in the section below on compilation. Note that this means that you are not allowed to use the
math.h
header since doing so would require you change the compilation command. - It should not crash or have any memory errors. If you encounter an error, your code should return from main or exit with status code
EXIT_FAILURE
- Your code should print the approximation of pi to the 50th decimal place. To normally print a float we would use the format specified
%f
, but to do this you would need to do%.50f
- Your code must have at least one helper function that is used by your code. Be sure to follow the style practice for functions in C that we went over in class
- Your code must be robust. Be sure you handle the wrong number of command line args and bogus input well. What we mean by this is that your code should not crash, have any memory errors and handle things “gracefully”. How exactly you handle the error is up to you, but a common way these situations are handled are by printing an error message to
stderr
and exiting with theEXIT_FAILURE
status code. If the autograder rejects how you handle an error but you think it is reasonable, reach out to course staff and we will either tell you what is wrong or give points back.
Allowed / suggested functions & headers
For this assingment you are allowed to write any helper functions you need, but you are restricted to using the following headers and the following functions. You do not need to use all of these, do what you think would be best for your code. If you do not see a function listed that you think should be ok to use, please ask and we can allow it or disallow it.
- stdlib.h
exit
EXIT_SUCCESS
EXIT_FAILURE
- stdio.h
atoi
fprintf
printf
strtol
- ctype.h
isdigit
isalpha
isspace
-
string.h
strlen
Compilation
You must also come up with the compilation command you will use for this assignment. This is not as hard as it may sound, it should have been covered in one of the first two lectures. Your compilation command should
- take in your
approx.c
file, and output an executable calledapprox
- Use the same compiler as used in class
- compile with extra information for a debugger
- have the “enable all warnings” option turned on
Once you have this command, you should use it to test your program locally and also store it in as the only thing in compile_command.txt
, which you will submit on gradescope alongside approx.c
Submission
Please submit your completed approx.c
and compile_command.txt
to Gradescope