For this lab session, we will use the lab desktop PC and the real pelogin system
so you can get a feel for working in the Practical Exam (PE) environment.
Read the PE0 page
for the exam procedure.
This lab is still ungraded, and you can ask your TA for help.
Find Your Practice Credentials
Your practice username and password will be provided in a comment on the
Canvas assignment CS1010 PE Practice Credentials once it is published.
These are the credentials to use for this lab session.
The PE0 page
explains how you will receive your credentials for the actual exam.
Open the CS1010 course on Canvas, open CS1010 PE Practice Credentials,
and read the comment containing your username and password.
Keep these details available for the two login steps below.
If you cannot find the assignment or your comment when the lab begins,
ask your TA for help.
Log In to the Lab PC
Use your lab desktop PC for this session
If it is running Windows, save any open work and restart it. Select Ubuntu
from the operating-system menu. Ask your TA if you cannot find this option.
If Ubuntu is already logged in to another account, log out first
At the Ubuntu login screen, enter the practice username and password
from the Canvas comment. If another username is shown, choose the option
to enter a different username
After the desktop appears, open a terminal with Ctrl+Alt+T,
as described on the PE0 page. You can also open Terminal from the
applications menu
Connect to pelogin
Logging in to Ubuntu gives you a desktop on the lab PC.
You must now connect your terminal to the remote PE system using SSH,
as practised in Tutorial 3.
This session uses the real pelogin service, rather than Tutorial 3’s simulation.
In the terminal, type the following and press Enter:
ssh pelogin
SSH uses the username you used to log in to Ubuntu
If this is your first connection and you see the host-authenticity prompt,
type yes and press Enter
If asked for a password, type the password from the Canvas comment and
press Enter. Nothing appears as you type, not even asterisks; this is normal
Wait for the remote shell prompt, then run whoami. It should print your
practice username. The machine name in the prompt may differ from pelogin
Keep this terminal connected for the rest of the lab.
If you get a login error, ask your TA for help before continuing.
Copy the Lab Code to Your Home Directory
The starter code is in the shared, read-only directory /opt/course/cs1010/lab3.
Make your own copy before editing anything.
Here, ~ means your home directory on the remote PE system.
Run these commands in the terminal connected to pelogin:
cp -R copies the whole directory, including its subdirectories.
The --update=none option keeps any existing files in your copy, so repeating the command
does not overwrite work you have already started.
You should see activity-1, problem-solving-1, and problem-solving-2.
Work in ~/lab3 on pelogin for the activities below.
Use your terminal editor, make, and make test, as practised in
Tutorial 3.
Save your files regularly.
Your saved files remain in your remote home directory when you disconnect;
there is no separate submission step for this ungraded lab.
Preface
In Lab 3, we’re going to work on a few mechanics about arrays (not too many). And then mostly work on recursive problem solving. Some of these questions are also in your volume, we’re dedicating lab time to help guide you through the problem solving process. Up until before this lab, we’ve only given very small snippets. Today we will have you writing slightly bigger snippets.
As with the previous labs, do not immediately compile each program.
First predict what it will do.
Then run it, observe what happened, and explain why.
Activity 1: Arrays and Functions
The starter code for this activity is in activity-1/.
From the Lab 3 directory, run cd activity-1 before compiling these examples.
Return to the Lab 3 directory with cd .. when you finish Activity 1.
Part 1: One-Dimensional Arrays
Consider arrays-and-functions.c:
#include <stddef.h>#include <stdio.h>void change_number(int value) { value = 99; printf("inside change_number: %d\n", value);}void change_element(int values[], size_t index) { values[index] = 99; // Alternative 1 // values[index] += 1; // Alternative 2 // int x = values[index]; // x += 1;}int main(void) { int number = 10; int values[3] = {10, 20, 30}; change_number(number); change_element(values, 1); printf("number: %d\n", number); printf("values: %d %d %d\n", values[0], values[1], values[2]);}
What do you think will happen?
Before compiling:
Predict the value printed inside change_number
Predict the value of number printed in main
Predict all three values in values
Decide whether either function changes something in main
What are the valid row and column indices of grid?
How is the two-dimensional array parameter written in change_cell?
Which dimension is omitted and which dimension is specified in int grid[][3]?
Problem Solving Primer
As our tasks get bigger, here’s the problem solving pipeline we wish to teach you today:
Before writing your code, you are going to have to plan out your strategy. (Sometimes we call this whiteboarding)
You might have to identify whether any existing library function or given function already serves your needs. If not, what kind of functions do you need? Do you need to break the problem up into smaller logical steps?
Only then, start writing the code.
Whiteboarding
This is just a quick reminder of how to solve recursive problems from the lecture (since now you’ll get hands-on experience doing this in the lab itself).
Identify the simple/base case and how to solve it then return.
For all the other cases, figure out how to work towards the simple case, and make use of its solution to solve the main problem that we were given.
Draw shapes and scribble if you have to. It helps. Discuss with your lab and lab TA.
Problem Solving Practice 1: Warmup
Input: You’re given an array values of length length. There are between 1 and 100 elements in the array.
You are guaranteed that incrementing any element by 1 will not overflow an int.
Task: Your task is to increment every value in the array by 1. You should do so recursively.
The starter code for this activity is in problem-solving-1/.
Step 1.1: Identify the Simple Case
What’s the “smallest version” of the problem you can think of? In that case what should you do?
Step 1.2: Use the Solution to the Smaller Case to Solve the Current Problem
Given that in general our array might have n>1 elements, how should we head from n towards the simple case?
Let’s say that solving the smaller case is already handled. What else is there for you to do?
Step 2: Break the Problem up into Logical Steps (if Need Be)
As usual, following the recursive “template”, we’ve already broken the problem up into the simple case vs the remaining case. Plan out what you should write in your if-else.
Step 3: Start Writing the Code
Open up student.c in problem-solving-1/ and implement the function provided.
void increment_all(int values[], size_t length);
You need not worry about reading from input, that code has been written for you.
We will also print the result of your work.
From the Lab 3 directory, compile and run your program:
cd problem-solving-1make./increment-array
Run make test to check your program against the supplied test cases.
Providing Input
To provide input, run the program and type the number of elements, and then on the next line, the elements themselves separated by spaces. Like so:
5
1 3 1 -1 7
Press Enter after the values line; you do not need to send EOF.
If you did your code right, the program in this example should then print:
2 4 2 0 8
Problem Solving Practice 2: Mirror
Input: You’re given an array values of length length. You’re promised that length is even and between 0 and 100.
Task: Your task is to mirror the first half of the array into the second half.
The starter code for this activity is in problem-solving-2/.
Example: Given array {0,1,1,5,3,3,0,0}, the expected output is {0,1,1,5,5,1,1,0}.
Step 1.1: Identify the Simple Case
Identify the simple case for Mirror.
This is probably slightly trickier than the previous one. The same approach there won’t fit but perhaps we can take inspiration from one of the problems solved in lecture.
Hint
Remember reverse? Perhaps that, or helper functions based on it, might be useful here.
Step 1.2: Use the Solution to the Smaller Case to Solve the Current Problem
In general, when our array has n>2 elements, how should we make it head towards the simpler case?
Hint
Again, think about reverse. Copy-pasting it will not help, but it, or helper functions based on it, might be useful here.
Step 2: Break the Problem up into Logical Steps
Lay out your general strategy first. What do you do in the simple case? What do you do in the general case? Do you need any additional functions?
Hint
You just need to be able to copy elements from one index into another. Thinking in terms of reverse, or helper functions based on it, might be useful here.
Step 3: Start Writing the Code
Open up student.c in problem-solving-2/ and implement the function provided.
void mirror(int values[], size_t length);
You need not worry about reading from input, that code has been written for you.
We will also print the result of your work.
From the Lab 3 directory, compile and run your program:
cd problem-solving-2make./mirror
Run make test to check your program against the supplied test cases.
Providing Input
To provide input, run the program and type the number of elements, and then on the next line, the elements themselves separated by spaces. Like so:
6
1 2 5 7 9 0
Press Enter after the values line; you do not need to send EOF.
If you did your code right, the program in this example should then print:
1 2 5 5 2 1
For an empty Mirror array, enter 0 and press Enter. No values line is needed.
Problem Solving 3: Grey Codes (Volume)
This exercise discusses the actual Volume question on Grey Codes to help you
think of the solution.