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

  1. Review the commands for navigating the file system

  2. Setup your GitHub repository for labs

  3. Setup and practice with Visual Studio Code, a text editor

  4. Learn to compile and run a C program from the command-line

  5. Submit your work for Lab #1 on Gradescope

  6. 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:

  1. 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.

  2. 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 and

  • Run 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:

  1. Compile hello.c using clang and then run the resulting executable. Did you give it a name with the (-o flag)?

  2. 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.

  3. 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

  1. fill in the required fields in the header comment,

  2. make the required change to the two_plus_two function, and

  3. push your changes your repository on Github, and then

  4. 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

  1. What do you expect to see when you run the command ls *.c from within your lab11 subdirectory.

  2. What do you expect to see when you run the command ls *e*.c from within your lab1 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.