Lab #1: Workflow¶
Due Date Wednesday, March 30th at 9pm.
The purpose of this lab is to familiarize you with some of the tools you will use in CS 152 and with the workflow for the course.
Students come into CS 152 with different levels of experience. If you are confident that you have already mastered the skills covered in a given section feel free to skip it. Do not skip the GitHub Classroom or Gradescope sections.
You must setup your labs repository on Github (following the provided instructions), complete the required Deliverables and upload your repository to Gradescope.
This lab should be completed in the Computer Science Instructional Lab (CSIL).
Objectives¶
Review the commands for navigating the file system
Setup your GitHub repository for labs
Setup and practice with Visual Studio Code, a text editor
Learn to compile and run a C program from the command-line
Submit your work for Lab #1 on Gradescope
Learn about useful shortcuts
Open a terminal window¶
Open a terminal window using the keyboard short-cut CTRL + ALT +
T
. (CTRL
is short for the control key.)
The program that runs within a terminal window and processes the
commands the you type is called a shell. We use bash
, which is
the default shell on most Linux distributions, but there are other
popular shells, such as ksh
, tcsh
, etc.
Note
You should always cut-and-paste (and edit, if necessary) commands from this (and future) labs rather than retyping them.
Cut-and-paste is a little quirky on Linux. For most applications,
you use CTRL-c
to copy selected text and CTRL-p
to paste
it. For the terminal application, however, you must use
CTRL-Shift-c
to cut and CTRL-Shift-v
to paste.
For example, to cut text from Firefox and paste it into the
terminal window, you’ll use CTRL-c
to cut the text from Firefox
and CTRL-Shift-v
to paste the text into the terminal window.
You’ll save yourself a lot of hassle if you can get to the point where using these commands is automatic.
Man pages¶
A man page (short for manual page) documents or describes topics applicable to the command-line. These topics include command-line programs, certain programming functions, standards, and conventions, and abstract concepts.
To get the man page for a command, you can type:
man <command name>
So in order to get the man page for ls, you would type:
man ls
This command displays a man page that gives information on the ls
command, including a description, flags, instructions on use, and
other information.
Each man page has a description. The -k
flag for man allows you to
search these descriptions using a keyword. For example:
man -k printf
This command searches all the descriptions for the keyword printf and prints the names of the man pages with matches.
Type:
q
to exit from a man page.
GitHub Classroom¶
If you have not done so already, complete the Lab 1: Pre-lab.
As noted in the prelab, we are going to use GitHub Classroom in CS 152. While much of the workflow will be similar to working with GitLab—which many of you used in CS 151 in the winter—a few things will be different:
You will have one repository that you’ll use for the labs and another set of repositories, one per assignment, for homework;
The process for setting up repositories will be different; and finally,
Your repositories will reside on GitHub rather than on the CS GitLab server (mit.cs.uchicago.edu).
We are using GitHub classroom rather than GitLab because it has better integration with Gradescope.
Before we setup your Labs repository, we need to handle a few administrative tasks. You’ll only need to do these once on the CS machines.
Creating an SSH Key¶
If you took CS 121 in Autumn 2021, you can likely skip this subsection and move on to Environment variable setup.
When you log into the GitHub website, you will use the username and password associated with your GitHub account. However, when using Git commands from the terminal, things are a bit different. In particular, GitHub uses two mechanisms for authenticating yourself from the terminal: Personal Access Tokens and SSH Keys. We will be using SSH keys.
In a nutshell, an SSH key is a file that resides in your home directory, and which you can think of as a file that stores a secure password (SSH keys are a bit more complex than that but, for our purposes, we can just think of them as extra-secure passwords).
To create an SSH key, run the following command from the terminal:
ssh-keygen
You will see the following prompt:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa):
Press Enter (this will select the default file path shown in the prompt: /home/username/.ssh/id_rsa
).
Note
If, after pressing Enter, you see the following message:
/home/username/.ssh/id_rsa already exists.
Overwrite (y/n)?
This means there is already an SSH key in your home directory. You should proceed as follows:
If you are already familiar with SSH keys, and know for certain that you’d like to use your existing SSH key, type “n” and skip ahead to the “Uploading your SSH key to GitHub” section below.
If you do not know why you have an SSH key in your directory, it’s possible it was created for you if you’ve taken another CMSC class in the past. Type “n” and then run the following commands to create a backup of your existing key:
mv ~/.ssh/id_rsa ~/.ssh/id_rsa.bak mv ~/.ssh/id_rsa.pub ~/.ssh/id_rsa.pub.bak
Then, re-run the
ssh-keygen
command, press Enter when prompted for the file name, and follow the rest of the instructions in this section.
Next, you will see this prompt:
Enter passphrase (empty for no passphrase):
Just press Enter here. You will be asked to confirm (just press Enter again):
Enter same passphrase again:
Note
While it may seem counterintuitive, we don’t want our SSH key to have a passphrase (this is an added layer of security which we won’t need for this class; your GitHub account will still be secure even if your SSH key doesn’t have a password).
If all goes well, you should see something like (but not necessarily exactly) this:
Your identification has been saved in /home/username/.ssh/id_rsa
Your public key has been saved in /home/username/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:cBUUs2FeMCIrBlTyv/PGpBtNz0v235zvLykpoWIOS9I username@machine
The key's randomart image is:
+---[RSA 3072]----+
| .+.. . ..@+. |
| + o = * |
| + o . o |
| . o o |
| . S |
| . +.o. |
| . E ++..=. . . |
| o o+++o.oo oo.|
| .oo+. ...o.+O|
+----[SHA256]-----+
This means your key was created correctly.
Uploading your SSH key to GitHub¶
Now, we need to instruct GitHub to accept our SSH key. To do this, log into https://github.com/ and go to your Settings page (by clicking on the top-right account icon, and then selecting “Settings” in the drop-down menu. Then, click on “SSH and GPG keys”.
Now, click on the green “New SSH key” button. This will take you to a page where you can upload your SSH key. You will be asked for two values: a “Title” and the key itself. The title can be anything you want, but we suggest something like “CS 152 SSH Key”.
The value of the key is contained in the .ssh/id_rsa.pub
file in
your home directory. To print out the contents of that file, we can
just use the cat
command, which reads files and prints them:
cat ~/.ssh/id_rsa.pub
This will print a few lines of output starting with ssh-rsa
and ending in something like username@machine
.
Copy the whole output to the clipboard; you can do this by clicking and dragging the mouse from the first
character to the last character, and then pressing Ctrl-Shift-C.
Then, paste the key into the “Key” field on the GitHub page. Then click on the green “Add SSH Key” button.
To verify that you correctly uploaded the key, try running the following command:
ssh -T git@github.com
You may see a message like this:
The authenticity of host 'github.com (...)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?
You can safely enter “yes” here. You should then see a message like this:
Hi username! You've successfully authenticated, but GitHub does
not provide shell access.
This means your SSH key is properly set up (don’t worry about the “does not provide shell access”; that is normal).
If you are unable to set up your SSH key, please make sure to ask for help. You will not be able to complete the rest of the lab until you’ve set up your SSH key.
If you would like to set up SSH access from your personal computer at a later time, GitHub provides some pretty detailed documentation on how to do this in a number of different operating systems: Connecting to GitHub with SSH Please note that we may not be able to assist you with SSH issues on your own computer.
Environment variable setup¶
On Linux systems, it is common to set up environment variables (aka,
shell variables) for frequently used values, such as the name of your
home directory (HOME
) or the shell you are running (SHELL
).
By convention these variables are named using all capital
letters.
You can see the environment variables that are currently set for you, by running:
printenv
While these variables have been pre-set for you, you can also define
your own environment variables. Before we move on to creating your
first repository, we will define two environment
variables—GITHUB_USERNAME
and GITHUB_152_ORG
—that you’ll
need throughout the quarter. The first will hold your specific GitHub
username. The second will hold the name of the GitHub organization
that we are using for this class. You’ll see how these variables are
used below.
We have put together a simple shell script for setting up these
variables for you. To execute it, run the follow command, replacing
replace_me
with your Github username:
~ar0r/add_env_vars.sh replace_me
This command runs a shell script that adds the two environment
variables to a special file named .pam_environment
in your home
directory. (You can run cat ~/.pam_environment
to see the
contents of this file.) The code in this file is run automatically
every time you log into one of the CS Linux machines or create a new
terminal window when logged into a CS machine.
It has not, however, been run for the window you are currently using. To set up the variables for use in your current terminal window, run:
source ~/.pam_environment
To verify that the variable was set correctly, run the following:
echo $GITHUB_USERNAME
(The $
asks the shell that to evaluate the variable GITHUB_USERNAME
.) Try
running this command and see what you get.
If you ran the shell script and echo
command properly, the result
should be your GitHub username. If the result is replace_me
,
please rerun ~ar0r/add_env_vars.sh
with your GitHub username in place of
replace_me
. If the result is blank, check to make sure you used
the correct variable name with the echo
command.
In this section, you will work through a series of steps to initialize your repository.
Your repository is hosted on GitHub, but you can create a local copy in your home directory (we will refer to this as your local repository).
We strongly encourage you to use cut-and-paste, rather than typing
the commands by hand listed below. It is very easy to make a mistake,
such as leaving out a $
, when typying one of the commands by hand.
Step 0: Verify that your repository has been created on GitHub.
This section assumes you have already accepted the Labs invitation for
URL and that your repository has been created on GitHub. To verify
that your repository exists, open a browser tab to this URL:
https://github.com/uchicago-cmsc15200-spr-22/labs-GITHUB_USERNAME
where GITHUB_USERNAME
is replaced by your GitHub username. If you
are not able to open this URL successfully, please ask for help.
Step 1: Create a directory for your work this class and the labs repository:
cd
mkdir -p cmsc15200/labs-$GITHUB_USERNAME
cd cmsc15200/labs-$GITHUB_USERNAME
The purpose of the initial cd
is to make sure you are starting
from your home directory.
Notice how we’re using the GITHUB_USERNAME
variable that we
defined earlier. When you run the above commands, the shell will
automatically replace the text $GITHUB_USERNAME
with your GitHub
username.
The -p
flag to mkdir
tells mkdir
to create all the parent
directories if needed; i.e., if you don’t already have a cmsc15200
directory, it will create one, and then will create a directory for
your labs repo inside it.
The purpose of the second cd
is to move you to the directory where
you will do your work for this lab. Run pwd
to make sure you are
in the right place. (A little sanity checking goes a long way towards
avoiding mistakes.)
Step 2: Run this command to initialize a local repository:
git init
Step 3: Run this command to connect your local repository to your labs repository on GitHub:
git remote add origin git@github.com:$GITHUB_152_ORG/labs-$GITHUB_USERNAME.git
This command will not generate any output, if it ran successfully.
Step 4: Run these commands to connect your repository to the “upstream” repository that we will use to distribute code for this lab (and subsequent labs) and to pull the initial files for the lab:
git remote add upstream git@github.com:$GITHUB_152_ORG/labs-upstream
git pull upstream main
If these commands were successful, you will see something roughly of the form:
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 9 (delta 0), reused 9 (delta 0), pack-reused 0
Unpacking objects: 100% (9/9), 1.53 KiB | 9.00 KiB/s, done.
From github.com:uchicago-cmsc15200-spr-22/labs-upstream
* branch main -> FETCH_HEAD
* [new branch] main -> upstream/main
The exact number of files and/or objects may differ. If you get an error, please ask for help. It is important to pay attention to the error messages from git commands. Don’t just blindly run them. Make sure the output looks sensible and does not contain any errors or warnings.
Step 5: Set the name of the branch:
git branch -M main
This command will not generate any output, if it runs successfully.
Step 6: And finally, upload your local Git repository to GitHub, by running:
git push -u origin main
If this command fails, please ask the TA for help; you likely made a mistake setting up your environment variables or in Step 3.
Step 7: Do a sanity check.
Run ls *
. If everything went smoothly, you should find the following files in your Labs directory:
README.md
lab1:
hello.c lab1.c lab1.h lab1_main.c README.md
and in your repository on Github (see https://github.com/uchicago-cmsc15200-spr-22/labs-GITHUB_USERNAME
where GITHUB_USERNAME
is replaced by your GitHub username.)
Also, if you run:
git status .
in your lab-GITHUB_USERNAME
directory, the result should be:
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
You will be working on the lab1
subdirectory. Change into your
lab1
subdirectory to do the rest of the work in this lab.
You are now set to do the work required for Lab #1.
Note
The repositories created by GitHUb Classroom can be a bit hard to find from the standard GitHub interface. Fortunately, there is a page that lists your repositories for this course. We strongly recommend creating a bookmark in your browser to it: https://github.com/uchicago-cmsc15200-spr-22.
Git Refresher¶
Most students coming into CS 152 will have used the Git version control system and our GitLab server in a previous course. If you have not used Git, please let us know and we will make an appointment with you to explain the basics of Git.
For those of you who have used Git, here is a quick refresher.
Run
git status .
to get the status of the files in the current directory from Git’s perspective.Run
git add <filename>
to add a new file or file that has been updated to the list of files to be saved on the next commit. (<filename> should be replaced by the names of one or more files.)Run
git commit -m"Some message"
to create a commit from the files that you added since the last commit.Run
git push
to send your commit to the server andRun
git pull
to pull the most recent copy of the files from the server to your local machine.
Remember that the course staff does not have access to any files stored in your home directory or files on your laptop. All we can access are files that have been pushed to the Git server, so remember to always push your latest commits when you’re done working for the day or when you ask a question on Ed that will require us to look at your code.
If you are looking to learn more about Git, we recommend the Version Control lecture from the MIT Missing Semester Course as a good starting point.
Visual Studio Code¶
Visual Studio code is a modern text editor. From a terminal window,
you can open a file named hello.c
by running at the command-line:
code hello.c
This command will open your hello.c
file. If the file is empty,
you are likely in the wrong directory. Close VSCode, navigate to your
Lab # 1 directory (cmsc15200/labs-github-username/lab1
), and try again.
Note
VSCode may ask you about installing the C/C++ extensions. You can
ignore this suggestion for now when using the CSIL machines. Click
the x
to close the pop-up. We are working on getting the
extension set up globally, so, with luck, the editor will stop
asking this question.
When you install VSCode on your own machine, you will want to install the extension as explained in the installation instructions. Just not on the lab machines.
You can navigate around using the arrow keys or by using the keyboard short cuts discussed at the end of this lab.
You will want to configure VSCode for this class. In particular, you will want to make sure that pressing the tab key inserts four spaces instead of a tab character and you’ll want to add a “ruler” at 80 characters (to give you a visual reminder when your lines get too long). To ensure that the tab key inserts four space, look at the purple bar at the bottom of the VSCode window. If you see “Spaces: 4”, you’re all set. If you see “Tab” or “Spaces: 2”, you will want to change it. Just click on the item. You’ll see a pop-up menu. Choose “Indent with spaces” and choose 4 as the number of spaces to use.
To set up the ruler, click on the gear icon in the bottom left of the
VSCode window, search for “editor.rulers”. Click on “Edit settings in
Json”. Change "editor.rulers": []
to "editor.rulers": [80]
.
and save the file using CTRL-s
.
Editing, compiling, and running C programs¶
Before you start on this section, please make sure you are in the
lab1
subdirectory.
Now you will edit, compile, and run a C program from the command-line. The file, which you opened in the previous section, contains a classic program that prints “Hello world!” to the screen. To run the program, you first need to compile it. In this course, you will be using a popular C compiler called Clang. The most basic way to compile a C program using Clang is to run the command at the command-line:
clang hello.c
(Make sure you are typing at the command-line in your terminal window and not in VSCode!)
If the compilation is successful, you’ll see nothing at the terminal, but the compiler will have created an executable file named “a.out”. You can run the program by typing:
./a.out
The ./ syntax tells the shell to look in “the current directory for
the executable (a.out
). You should see the words “Hello world!”
printed in the terminal.
You can run the compiler with many more options:
clang -Wall -g -O2 hello.c -o hello
The arguments that start with a dash (-) are called options or flags.
The -Wall flag enables all compiler warnings. Even though the warnings will be irritating at times, do not ignore them! The warnings identify code that while technically legal in C may be incorrect or behave in unexpected ways. You should always use this flag.
The -g flag indicates that the compiler should include information for the debugger.
The -O0 flag tells the compiler not to optimize your code (which makes it easier to debug with the debugger). For production code, you would use a higher-level of optimization (O2, O3, etc).
The -o hello option tells the compiler to name the executable hello, rather than a.out, which is the default. To run the new executable, run:
./hello
Exercises:
Compile hello.c using clang and then run the resulting executable. Did you give it a name with the (-o flag)?
Edit hello.c to replace “Hello world!” with “Hello <your name>”. Save the file and then compile and run it. Did you get it right or did you introduce a syntax error? If you got an error see if you can figure out what might be wrong and try again. Ask for help if you get stuck. If you got it right the first time, try leaving out one of the double quotes (“) or the semicolon at the end of line 4 and see what happens.
Make a commit for this change and push it to the server:
git add hello.c git commit -m"Added my name to hello.c" git push
It is a good idea to create and push a commit when you have finished a task. That way if you run into a problem down the line you will be able to restore your work from the server.
Deliverables¶
Open lab1.c
in VSCode. Fill in the information required by the
header (that is, the comment at the top of the file) and replace the 0
in the return statement in the function two_plus_two
with 2+2
.
This file will be run with our test harness, which we’ll discuss more next week. This program consists of multiple files. To compile it, run:
clang -Wall lab1_main.c lab1.c -o l1
Once you have gotten your code to compile cleanly, you can run it using:
./l1
The output should be:
2+2 is 4
Once you have finished this task, add, commit, and push your changes to Github:
git add lab1.c
git commit -m"Finished deliverable for Lab #1"
git push
You can run git add -u
to add the files you have updated instead
of git add lab1.c
. Never use git add .
since it will likely
cause you to add executables, editor backup files, large output files,
etc that have no place in a repository.
Grading¶
Normally labs will be graded automatically. For this Lab, we will
assign points for completeness and for code quality. Your
completeness score will be determined by running our automated tests.
The code quality score for this assignment will be determined by
manually inspecting your header comment in lab1.c
to verify that
you completed all three required fields: name, sources consulted, and
people consulted.
The exact weights for each category will vary from one assignment to another. For this assignment, the weights will be:
Completeness: 97%
Code Quality: 3%
It should be easy to earn 100% on this lab. You just need to
fill in the required fields in the header comment,
make the required change to the
two_plus_two
function, andpush your changes your repository on Github, and then
upload your repository to Gradescope as explained in the next section.
Gradescope¶
Once you’ve completed the exercises, you must submit your work through Gradescope (linked from our Canvas site). Gradescope will fetch your files directly from your GitHub repository, so it is important that you remember to add, commit and push your work!
You can go ahead and remove the executable files (a.out
,
hello
, and l1
).
It is a good idea at this point to run:
git status .
You should see something like:
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
If hello.c
and/or lab1.c
are listed under “Changes to be
committed”, “Changes not staged for commit”, or “Untracked files, then
you have not successfully pushed your code to the server.
To submit your work, go to the “Gradescope” section on our Canvas site. Then, click on “Lab #1”. Since this is your first submission on Gradescope for this course, you will first need to connect your Gradescope account to GitHub. Click on the “Connect to GitHub” button. Pressing that button will take you to a GitHub page asking you to confirm that you want to authorize Gradescope to access your GitHub repositories. Just click on the green “Authorize gradescope” button.
Then, under “Repository”, make sure to select your uchicago-cmsc15200-spr-22/labs-GITHUB_USERNAME.git
repository (where GITHUB_USERNAME
is your GitHub username). Under “Branch”, just select “main”.
Finally, click on “Upload”. An autograder will run, and will report
back a score. If you uploaded everything properly, the score should
be 97. The other three points will be assigned by the grader; one
point each for completing the name, sources consulted, and people
consulted sections of the header comment in lab1.c
.
Note
If you took CMSC 12100 in Autumn 2021 and used GitHub with
Gradescope, you may need to authorize Gradescope to have access to
the uchicago-cmsc15200-spr-22
GitHub organization.
Try to upload your labs repo to Gradescope. If you can’t see your
repository in the list of possible repos when, then open the
Settings menu in GitHub. Choose Applications (in the Integration
subsection) and then choose Authorized OAuth apps. Click on
Gradescope and then grant access to the
uchicago-cmsc15200-spr-22
organization.
Some useful stuff¶
Most labs in this course will contains some material that is intended to help you become more fluent in Linux. Today’s topics—autocompletion, wild cards, and keyboard shortcuts–will help you do your work more efficiently.
Autocomplete¶
It can be tedious (and, when you are tired, challenging) to spell
directory or file names exactly, so the terminal provides an
auto-complete mechanism to guide you through your folder
explorations. To access this functionality simply start typing
whatever name you are interested in the context of a command and then
hit tab. If there is only one way to finish that term hitting tab will
fill in the rest of the term, for instance, if we typed ls b
and then
hit tab it would automatically finish the word ls backups and then
await our hitting enter. If there is MORE than one way to finish a
term, like if we had another folder called backups-old, then hitting
tab twice with cause the terminal to display all of the options
available.
Training yourself to use auto-completion (aka tab completion) will save you time and reduce the inevitable frustration that arises from mistyping filenames when you are tired or distracted.
Wild Cards (using an asterisk)¶
Sometimes when we enter a string, we want part of it to be variable, or a wildcard. A common task is to list all files that end with a given extension, such as .txt
. The wildcard functionality, through an asterisk, allows to simply say:
$ ls *.txt
The wildcard can represent a string of any length consisting of any characters - including the empty string.
It is important to be careful using wildcard, especially for commands like rm
which cannot be undone.
Exercises¶
What do you expect to see when you run the command
ls *.c
from within yourlab11
subdirectory.What do you expect to see when you run the command
ls *e*.c
from within yourlab1
subdirectory.
Keyboard Shortcuts¶
Used at the Linux prompt, the keyboard shortcut Ctrl-P
will roll
back to the previous command. If you type Ctrl-P
twice, you will
roll back by two commands. If you type Ctrl-P
too many times, you
can use Ctrl-N
to move forward. You can also use the arrow keys:
up for previous (backward), down for next (forward).
Here are few more useful shortcuts:
Ctrl-A
will move you to the beginning of a line.Ctrl-E
will move you to the end of a line.Ctrl-U
will erase everything from where you are in a line back to the beginning.Ctrl-K
will erase everything from where you are to the end of the line.Ctrl-L
will clear the text from current terminal
Play around with these commands. Being able to scroll back to, edit, and then rerun previously used commands saves time and typing! And like auto-completion, getting in the habit of using keyboard shortcuts will reduce frustration as well save time.