Category Archives: Labs

PR1EN2: Conditional statements

Lab materials

Tasks

This lab has two base tasks, first one simulating a cash register and the second one simulating a store food scale. The first task is extended by an extra task, adding support for bonus point management.

Task 1 [W02-1]: Cash register

With this task, we’ll create a simple cash register application with the goal of trying to compose different conditional statements. The task is provided with a starter code to start you off. Base your solution on the starter code, write your code statements after the comments specifying what to do!

Requirements:
  • Program must be logically identical to the given algorithm
  • Program must be built on the base code given. Your task is to add the missing printf , scanf , conditional statements and calculations. Use the code comments and the activity diagram as a reference.
  • Don’t change the variable naming or the program structure
  • Recommendation: To check that the values are correctly read and program behaves as expected, add printouts to check the variable values after mathematical operations.

Download task 1 starter code: [et] [en]

Algorithm

Testing

I’m proposing a series of tests for the program you are about to create. NB! I’ve left at least one important test case untested. Can you figure out which one?

Click me to see the test cases!

Test 1: Client is not offered any discount, successfully completes the payment. Also testing floating point values.

Test 2: Client has the loyalty card and gets an extra discount.

Test 3: Client has exactly the required amount of assets on their card.

Test 4: Client that is only able to afford the purchase after the discount.

Test 5: Client with not enough assets.

Test 6: Client, who does not know their PIN code.

Task 2 [W02-2]: Food scale

In this task you will create a program, that simulates the food scale in a grocery store.

The UML activity diagram to structure your program on will be created in class. Your program must match or exceed the functionality described.

Requirements
  • You must have at least four products available.
  • Products are represented as pairs of product codes (integer) and names (e.g. 1 – banana).
  • The user inputs an integer product code and a real numbered quantity (in kilograms) from the keyboard.
  • You must handle matching the product code to the price of 1 kg in the switch  statement.
  • User will be displayed the total price only if a valid product code and weight are entered.
  • The given price(s) must be given with 2 decimal places.
  • Invalid product code and weight must trigger an error. There is no need to specify which error occurred. In case of an error, price must not be shown!

Download the starter code for task 2: 2_2_scale_base.c

Algorithm

A copy of the algorithm for those who either reach the second task more quickly during the lesson or lose their own copy of the algorithm. The algorithm will also be solved together in class with additional commentary

Testing

Test 1: Correct inputs will give us a total cost.

Test 2: Invalid product code triggers an error.

Test 3: Invalid weight triggers an error.

Extra task [W02-3]: Bonus account

The extra task is an extension of the first task. To do this, we’ll add an option for the user to use bonus points.

While solving the task, think carefully about everything that could go wrong at each stage of the transaction and how those issues are related!

Note: as a result of solving this task, you will end up with one long piece of spaghetti code — everything in a single function. We will start fighting against this from fourth week.

Requirements
  • Add user’s bonus points count to the program, it should be initialized. Bonus points can only be integers (e.g., 1 bonus point, 15 bonus points).
  • Before completing a transaction, the user is shown their total bonus points and the maximum number of points they are allowed to use for this purchase, according to the rules of using  bonus point.
  • Then the user is asked whether they want to use bonus points. If yes, the program asks how many they wish to use.
  • Bonus point rules
    • 1 bonus point equals 1 euro cent
    • A maximum of 90% of the purchase can be paid with bonus points, calculated after discounts
    • If the user enters a number of bonus points greater than what they have or greater than what is allowed for the purchase, the maximum permitted amount is used instead
  • The rest of the transaction logic remains as specified by the base task
  • At the end of the transaction, the user is shown the remaining balance of their bonus account
Necessary knowledge

As a reminder from the previous lesson – the quotient of two integers is always an integer. If you need a division where the result must be a floating-point number (i.e., a number with a decimal point), then at least one of the numbers involved in the division must be a floating-point number. This turns the entire operation into a fractional division.

For example, 1 / 100 gives the integer 0, but 1.0 / 100 gives the floating-point number 0.01.

When multiplying by a real number, this issue does not occur — e.g., 10 * 0.01 results in 0.1.

Testing

In the first example, the user is applied discount. Without the discount, the purchase would not be possible.

In the second example, the user chooses not to use their bonus points.

In this example, the user wants to use more bonus points than they have, so the amount is overwritten. The transaction does not go through because there is not enough money, and the bonus point balance remains unchanged.

After the class, you should 
  • Know what is a truth table and how to read them
  • Be able to form conditional statements consisting of multiple conditions
  • Know what De Morgan’s law is and how to apply it
  • Know how to use inversion and short forms for conditional statements
  • Be able to initialize integers and floating point values when declaring them
  • Be able to write nested conditional statements
  • Be able to alter the variable value relative to the old value, on the same line
  • Be able to use and print floating point values while specifying number of decimal places
  • Understand how switch statements work and how to use them in code
  • Be able to model a switch statement in an activity diagram
  • Know how to use swim lanes
  • Know how to have multiple different endings in both programs and in activity diagrams

Additional content

2. lab: pointers

Lab content

 

After the class, you should be able to

  • Understand what a pointer is
  • Declare different types of pointers
  • Understand some of the use cases for pointers
  • Understand what a NULL pointer is
  • Understand the dereference and address operators
  • Understand why some variables when reading with scanf() required & and some didn’t
  • Find the address of any variable
  • Pass addresses of variables to functions (by reference)
  • Better understand the difference of passing arguments to functions by value and by reference (originally simplified as copy, original)
  • Understand how arrays are actually passed to functions and thus why we can alter them without any extra steps
  • Understand pointer arithmetics
  • Know what a memory address looks like
  • Understand that there are different width memory addresses and why  it is like that

Additional content

 

PR1EN14: Command line arguments

Lab materials

Lab tasks

For this lab, you will have one main task with 2 advanced tasks that add extra functionality and features to the base task.

Lab task: calculator

For this task, you will build a calculator that works by getting its input from the command line

Requirements
  • You will create a simple calculator, that
    • can do addition, subtraction, multiplication and division
    • supports positive integers as operands
    • only does one operation at a time (e.g. 3 + 6)
  • Have a precision of 2 places after the comma
  • Both the operands and the operator will be given as command line arguments
    • E.g. an addition operation would look like this:
  • Program is not allowed to ask for any input during its execution
  • Your calculator must detect the following errors
    • Wrong argument count
    • Unknown operator
    • Non-numeric operand
    • Division by zero
  • When an error occurs, you will both present the specific error message and the guide how to use your program
Recommended list of functions
  • Display help
    • Shows how to use the program
  • Argument check
    • Checks for number of operands
    • In advanced, checks for --help  argument
  • Error management
    • Displays the specific error message
    • Calls the display help function
  • Operand check
    • Checks if the operand is numeric
    • Returns the operand converted to a number (e.g. int)
  • Calculation
    • Identifies the operation and calculates the answer
    • Returns the answer

You may also benefit from creating a function to check for the operator.

Example

To test a completed program, we recommend downloading the sample and seeing how it works.

To see all the test cases for the program, check the next paragraph.

Example 1: Input is OK and the program prints the answer

Example 2: Program is executed without arguments. An error message and a how to use guide is provided.

Test cases

Advanced task 1: real numbers

Change your program in a way that it would support all real numbers. You must add support for both negative numbers and numbers with decimal places.

Test the following

  • -3.3
  • 3-3
  • -3-3
  • 3.3.3

Advanced task 2: Extended functionality

Add the following functionality to your program

  • Taking a square root
  • Power function (xy)
  • Displaying help using the argument --help  without causing an error to occur.

All added functions must be present when help is shown.

After the class, you should be able to

  • Understand what a command line argument is
  • Know other programs that use command line arguments
  • Be able to accept command line arguments in C code
  • Know that main() function has multiple forms
    • Understand what argument count is
    • Understand what argument vector is
  • Know what is the first argument passed to a program
  • Know how argument count changes depending on how many arguments are passed
  • Understand that * and [] interchangeable
  • Understand what * means in the command prompt and how to pass such characters to programs
  • Understand how to pass multiple words as a single argument
  • Be able to convert strings into integers, floats

Additional content

8. lab: functions

Lab content

Lab tasks

Task 1: finding results from an array

The purpose of this task will be to create a program, that:

  • Reads 5 integers from the user that will be in between -100 and 100.
  • Prints the entered numbers out.
  • Finds and prints the arithmetic mean with 2 places after the comma.
  • Finds and prints the smallest member in the array.
  • Allows the user to enter a number and checks if it exists in the array or not.

The task has the following limitations (in addition to previous practices):

  • All of the functions described below will have to be implemented and used to find the results.
  • Constants defined using macros must be passed as a function parameter and not directly used in the functions.
  • If the function’s purpose is to find a results (e.g. arithmetic mean, smallest number, …), the result must be returned to main(). Side effects (printing the results within the functions) is not allowed.

Solve the program step-by-step. Test each function after creating it before proceeding. Avoid writing the code without functions at first! The functions given below are in the order we recommend writing them.

We have written a simple writeup on the parameters for each functions.  If you wish, you can add additional parameters to the second function (read array), but nothing else!

The writeup on the functions is simplified and allows the developer to make some decisions on their own. It is not enough to be used as a sample for homework 2!

1. function: reading an integer

Description: Reads one integer from the user, that is checked to be in the allowed range. The function must not return before the entered value is within the allowed range. If the user entered number wasn’t between the allowed minimum and maximum, the user will be warned and prompted again.

Parameters:

  • integer – minimum allowed value.
  • integer – maximum allowed value.

Return: integer, that is between the allowed minimum and maximum.

2. function: filling an array

Description: This functions reads n integers and stores them into the array. To use each integer, the previously completed function (reading an integer) is called. It is done repeatedly in a look for each array member that needs to be read.

Parameters:

  • integer array – the array that will be filled.
  • integer – array length.

Return: none.

3. function: printing an array

Description: Function prints values stored in the array.

Parameters:

  • integer array – the array that will be printed.
  • integer – array length.

Return: none.

4. function: arithmetic mean

Description: Function finds the arithmetic mean from the array and returns it.

Parameters:

  • integer array – array, that contains the members of which the average will be calculated.
  • integer – array length.

Return: float – arithmetic mean.

5. function: minimum value

Description: Function finds the smallest member of the array and returns it.

Parameters:

  • integer array – values from where the minimum value will be searched for.
  • integer – array length.

Return: integer – smallest number in the array.

6. function: check if value in array

Description: Function looks if the entered value is within the array or not. The result will be coded as an integer and returned.

Parameters:

  • integer array – values from were the search key is being looked for.
  • integer – array length.
  • integer – the value that is being looked for.

Return: integer / boolean – was the entered number present in the array or not.

Advanced: multiples of n to a new array

  • User enters a multiplier (positive integer)
  • Create a function that will create the new array
    • Values where the absolute value is a multiple of the entered multiplier will be added to the new array. New array members must also be absolute values.
    • Function itself must not print out the new array nor call a function to do so.
  • The newly created array must be printed out. Use a function that already exists.

Task 2: Converting an existing code to use functions

Take the following code and split it into functions:
https://blue.pri.ee/ttu/files/iax0583/warehouse_kontaktope.c

Create the following functions, move the code from main to those functions:

  • Array print (without return, code reuse)
  • Print message about how much will fit (without return)
  • Sorting (without return)
  • Combining in sorting facility (returns number of items moved to the third array)
    Note: This function can work with code reuse (called twice), but doesn’t have to!

Advanced: weight limit

Create a limit for the cargo exiting the sorting facility.

E.g. a truck can deliver up to 1500 kg at once. Fill it with heavier items first. If some items don’t fit the limit, try if a lighter item will fit.

Print out the items that did fit on the truck and then fit separately the items that were left in the sorting facility.

After the class, you should

  • Understand what a function is
  • Understand that we have been using functions from the first week. Both functions that return values and those that don’t!
  • Understand, that we can create functions just like those we have been using.
  • Understand the following terms
    • Function prototype
    • Function return type
    • Function arguments
    • Function parameters
    • Function header
    • Function body
  • Be able to create proper functions
  • Be able to pass variables and arrays to functions
  • Be able to store the value returned from a function
  • Be able to reuse functions with different arguments
  • Be able to divide your code to functions
  • Have a small list of universal functions that you can reuse in future codes!

Additional content

Week 7 Linux task

Download VIM configuration file
1. Go to your home directory

2. download the file

Decide on where to put your program(s) for this lab.
e.g. ~/P/IAX0583/ or something similar. Make sure that folder exist, if necessary create a new folder.
Use cd  to navigate, mkdir  to create a directory

Download the archived test program

You need to unzip the file
Use the program called unzip

You may need to manually make it executable
You use chmod  for this

Note: From this point on you can try to run the program provided. I recommend you try this out now! The program will stop when an unmet requirement is encountered.

Copy over an additional data file with the secret

Go to the M: folder (~/M/). Find your lecturer’s directory and go to it. In there you will find a hidden directory – go to it (it starts with a dot).

Inside you will find a .dat file. Copy that file over to the same folder as the test program. For this you will need to use the cp  command. Specify the file you want to copy and the path you want to copy it to.

To test if this worked, run the program and see if it finds the secret!

Next up you need to create a file with your matricula

For this, go back to the folder with your lab files. For this one, I’ll provide two possible options.

Option 1: Open up your favourable command line text editor, write a file called “matricula”

Vim guide:

    • Start by writing vim matricula  to create a file called matricula and open it in Vim.
    • Press ‘i’ to enter writing mode.
    • Now write your matricula.
    • Press ‘esc’ to exit write mode.
    • write :wq  in normal mode to write the file and exit

Option 2: This is what most people actually would do. They would use the echo command and redirect the output streamto a file, e.g. echo "text" > file

Write another program that will print out “Hello world!”

Again use a command line text editor. We recommend Vim, as it supports C code, but you can use any other editor as well.

Once done, compile the program. Use “-o hello” to specify the name of the program as “hello”

Now run the test program that you downloaded from us. If everything was successful, you get a new file with instructions.
Follow the instructions or if necessary, fix the mistakes.

PR1EN9: matrices

Lab content

Lab tasks

This lab has two gradable tasks. Second task is extended by two extra tasks.

Task 1: Calculating various results from a matrix

In this task we’ll practice navigating a matrix and finding results from it.

The task is graded separately in 3 parts.  Look for “Graded parts” below.

To start, download the following files.

Note: the task must be shown with stream redirection with the provided data file in order to be accepted!

Requirements
  • You have been given a starter code and an input file to use
  • Program must be shown using stream redirection
  • Add the printout of the matrix
  • Find and print the following results
    • The sum of negative elements on the main diagonal
    • The product of positive elements above the anti-diagonal
    • The greatest value in every row
  • All values must be stored as integers. Data types such as float, double and such are not allowed.
  • If you want to use smaller or bigger data types than a 32-bit int, you must use it precisely (e.g. through inttypes.h ). Data types such as long  and long long  are not allowed.
  • The solution must be cross-platform. Formats such as %ld  and %lld  are not allowed.
  • You must complete at least the listed functions below under “required functions”.
Required functions

You need to have at least 5 user-defined functions created in your program. You are allowed to create more if it suits the purpose.

  • Reading the matrix. During the function, all values were be stored into your 2-dimensional array (matrix). This has been done for you.
  • Printing of the matrix. During the function, the matrix will be printed onto the screen as shown in the example below. Function has no return value. Prototype for it has been done for you.
  • Finding the sum of negative numbers from the main diagonal. Function returns the sum to main() function, where it will be printed. Side effects are forbidden! Prototype for it has been done for you.
    NB! Think carefully about which values need to be summed up and watch out for excess work. Check out the indexes where your values are and make sure that you only go through those and nothing else. E.g., going through the entire 49-member array only to add up 7 values is not ok. Imagine if this was a 1000 x 1000 matrix – in that case you would visit a million numbers only to find 1000 of them. This would make the useful work to be 0.1% (reduction in efficiency is exponential if you go through the entire array).
  • Finding the product of positive values that are positioned above the anti-diagonal. Function returns the product to main() function, where it will be printed. Side effects are forbidden.
  • Finding the greatest values in each row. This one is entirely up to you how to design. You can have side effects and print the results inside of this function. You can add some helper functions as needed as well.
Grading

The task has 3 graded parts, marked separately.

There are 2 requirements which must be completed regardless of which part you intend to present

  1. Program must be executed using stream redirection
  2. Matrix must be printed on the screen

Separately graded parts

  • Part 1: the sum of negative elements on the main diagonal
  • Part 2: the product of positive elements above the anti-diagonal
  • Part 3: the greatest value in every row
Hints
  • Look at how ReadMatrix()  is written. You can write the parameter list for your other functions based on this
  • Printing: Again, take inspiration from ReadMatrix()  function. This already has everything you need to go through all the positions. Now you just need to format the printout nicely. To figure out the line change, think of what is the purpose of inner and outer loops!
  • Part 1: Write the indexes that you need to sum up. Take a look at those indexes and think of how many variables (and loops) you even need to go through all of them!
  • Part 2: Remind yourself what happened during an integer overflow!
  • Part 3: You can pass a single row of a matrix into a function. For this, we will specify the index of the row we wish to pass as well as pass the length of that row. This way you can re-use a function that you’ve created previously. E.g. FindMaxValue(matrix[rowIndex], rowLength)
Testing

This include the answers expected from the given matrix.

Task 2: Cinema hall

We have been given a layout with the current bookings for a cinema hall. It is represented as a 2-dimensional array. Your task will be to correctly interpret the values to display the hall plan.

All seats in the hall are coded with the following integers:

  • 0 – the seat does not exist at this location
  • 1 – the seat is free
  • 2 – the seat is already booked

The array position 0, 0 corresponds with the top left seat of the movie hall.

Download the starter code with the hall plan here: https://blue.pri.ee/ttu/files/iax0583/aluskoodid/9_2_cinema_init.c

Requirements
  • Print the hall plan. Program’s output must match the one given in the sample
    • Row numbers are placed on the left side
    • All rows start with the seat number 1. You must account for missing seats (and not count them – look at the example)
    • Free seats are marked as seat numbers
    • Missing seats are marked as an upper case ‘X’ character
    • Seats that don’t exist are not depicted
    • The location of the screen is shown in the plan
  • Ask the user for a seat (row, seat number) and print if it is free or not.
  • At minimum, you should have 2 functions besides main. One for printing the plan, another for checking the availability of the chose seat. You are free to create more as you see fit.
Workflow recommendation
  1. Print out the floor plan just as regular matrix with all numbers. Do not try to adjust what’s printed yet.
  2. Start altering the output (interpreting the coded values in the array). Create a conditional statement to print “nothing” instead of the code that represents missing seats
  3. Continue to interpret the other codes.
  4. Now that the floorplan is printed, print out the row numbers on the side.
  5. Ask the user for their preferred seat. Don’t forget to sanity check them!
  6. The row index can be calculated in one step. Column index has to be adjusted for the missing seats.
  7. Print out the indexes in the array data structure to validate that you got the correct position! 
  8. Now finish the program.
Hints
  • The floor plan is flipped compared to the array indexes. It may help you to draw it out and write the indexes for the first and last row compared to the floorplan.
    • Row 14 has the row index of 0
    • Row 1 has the row index of 13
  • To figure out the seat number, use a separate counter
  • A really clean solution to handle such a coded integer is a switch()  statement.
Testing of the program and samples

NB! The sample also uses colors in code, your solution doesn’t have to (but can 🙂 )

We’ve added a small debugging line where we are showing the index of the array we are checking for seat availability. It’s recommended to add it to yours as well, as it will be easier to check for correctness of it.

Sample output after solving the base task:

Click me to see the image

Sample output after solving both extra tasks:

Open me to see the image

Extra task 1: n tickets

Lets add a feature so that the user can book multiple tickets with one purchase. Add this to the base task.

  • User is asked for the number of tickets required.
  • All of the seats offered must be in the same row, next to each other.
  • Use the entered seat position as the starting point for your search. The other seats can booked to the left or to the right of the chosen seat, including to both sides at the same time.
  • Display the offered seats

Extra task 2: confirmation

Lets add a confirmation before the seats are booked

  • You must have both the base task and extra task 1 completed and in the same program for this.
  • After giving the offer to book the seats, prompt the user a confirmation if the offered seats are OK.
  • If the user refuses the seats you offered or there were not enough seats available at the chosen location, allow them to choose again (both seat position and number of tickets)

Hint: There are 3 coded values in the initial matrix. If you wish, you can add them. As an alternative, you may just want to make a copy of the initial matrix.

After the class, you should

  • Be able to use various length integers in code, including a 64 bit integer in cross-platform compatible code.
  • Understand how integer overflows happen in code
  • Be able to visualize a two-dimensional array
  • Understand how to declare and index a two-dimensional array
  • Be able to index only a specific part out of that array (e.g. first row, last row, first three rows, second element from the third row etc.)
  • Understand and be able to use matrix diagonal properties
  • Be able to go through the array both row by row and column by column

Additional content

PR1EN6: Arrays continued

Lab content

Theory nugget 1: Passing text to a function

Many functions that otherwise seem generic and easily reusable, such as input and output functions, might have an issue that the printed text doesn’t work for the specific use case

One way to handle this is what we did before – we printed the text separately and called the generic input/output function (such as read array, read number, print array etc). In general, this still remains my recommendation. This way you have less complexity that could otherwise hinder the reusability of this function.

However, as an alternative, I’ll give another idea. Let’s follow the basic principle of when to create a function – if you are copy-pasting code because you have a marginal difference between them, try to find a way to handle it using function parameters. This will now offer us a solution – we can pass the text we wish to print as a function parameter.

This works quite well if we want to give the user an input prompt on entering a value, such as an integer. It also can work reasonably well for printing an array with a label before it.

NB! Two additional important thoughts! Both of which we will talk in greater detail in the second part of this semester.

  1. Text is an array, composed of individual character. Each character also has its own index.
  2. As opposed to integer and float arrays, we do not need to pass the length of a text array to print it (we still need it for processing). This is due to a special character that is placed right after the last symbol, that terminates the the end of the string.

Theory nugget 2: Passing an array vs a member of an array

In the last lesson, we discussed how arrays behave with functions. Let’s remind ourselves of some key points

  1. Arrays were passed as the reference to the location of the array.
  2. We can manipulate arrays in functions. Modifications are persistent.
  3. We cannot determine the length of an array that was passed to a function, thus we must always the length of the array as well.
  4. When passing an array to a function, we use the name of the array only, nothing else.

Additionally, as a reminder, when we put the square brackets after the name of the array in the middle of the code, we are indexing the said array.

This leads us to the following example, where we are highlighting passing an array to a function vs passing a member of the array to a function.

Tasks

In this class, you need to solve two tasks. The first task is extended by two extra tasks.

Lab task 1 [W6-01]: Composing new arrays

The lab task is based on an algorithm specified by: https://blue.pri.ee/ttu/programming-i/algorithm-tasks/#Algorithm_3_Reordering_negative_and_positive_numbers

The algorithm is provided below. The task itself (as per requirements) also includes additional functionality, that is not described by the algorithm.

Algorithm

Requirements
  • Program must be based on the provided algorithm and extended based on the requirements listed here.
  • The user is asked for 6 numbers, which are stored in an array.
  • A second array is created based on the rules set in the algorithm. In the algorithm, it’s referred to as the reordered array. In the task description, we will also refer to it as the algorithmically created array.
  • A third array is created, which will only contain numbers greater than zero. The length of the array might end up being smaller than the initial array.
  • After all 3 arrays are populated, they are printed out.
  • The program must contain a total of four functions. One to read the numbers, one to print an array, one to compose the array made of positive numbers and one to compose the array specified by the algorithm.
  • All functions for creating and printing of the arrays must be called from the main()  function.
Hints and recommendations

Start by completing the reading and printing of the array functions. Both of these you have done previously. Create the necessary array and, if you wish, reuse the functions you created last week. If you choose to copy functions from previous week, don’t forget to copy the function comment!

Now lets create a function to make the algorithmically created array. First, create a new array that has the same length as the array where the user entered numbers were stored to. Remember, you cannot return an array from a function. You need to declare this array in the main()  function and pass it to this function. To create the new array, follow the algorithm provided. Then print out the array you just created. The code should look something similar once completed (names of functions and variables can be different).

If you feel that your main() function is starting to be overcrowded, the printed text can be passed with the function call. Look at the first theory nugget.

Now move on to the last function, where you need to create an array with only positive numbers. Most of it will look very similar to what you just did, just shorter as you don’t need to go through the array twice. Think carefully about how to get the length of the new array back to main()  function! This array will likely be shorter and have unused slots in the end.  Once you have the length of this array, call the printing function from main()  to print out the third array.

Testing

In the first test, we’ll run through the most typical case for this program, where we have both positive and negative numbers as well as a zero.

The program should should also account for the situation where no positive input values were given.

Lab task 2 [W6-02]: Array indexing and comparisons

The second task is about indexing into an array to pick out specific member values and performing basic operations on it.

Requirements
  • Read 5 integers from the keyboard
  • Ask user for two indexes.
    • Check that they are within the array bounds before proceeding. If needed, prompt the user again!
    • Numeration must be the same as when asking for input
    • Recommendation: Print the values corresponding to those indexes from the array to check for correctness before proceeding
  • Using those two values you found, find the following results
    • Compare them, print out their relation to each other (e.g. is the first number smaller, greater or equal to the second)
    • Create a division operation. The operation must be formed in a way, that the dividend is always greater than the divisor. If needed, swap them around.
    • Division answer must be given as a real number. Display 1 place after the comma.
  • For this task, you need to create four functions. Functions are described for you in varying detail.
Functions to create

1. Reading the array. Reuse the code that you have done before. Copy it in with its comment.

2. Reading the index. For this, you need a new function. Let’s make it a generic and reusable function that you can use in the future – reading an integer in range. This way you can use it whenever you need one (e.g. from 0 to 5; from -10 to 10; etc). If you completed the extra task from last week, you will likely already have this function.

I’m proposing two ways to write this function. Pick the one that you prefer and implement it.

First version assumes that the question (what to enter) is presented to the user before this function is called.

The second version will present the prompt to the user by the function itself. This requires the prompt to be passed to this function (theory nugget 1).

3. Comparison of values. For this function, you need to pass the two numbers you are comparing. You need to print both numbers and their relation to each other (which one is bigger or are they equal). Output should be using the format “a < b”, “a > b” or “a = b”

NB! To pass numbers to this function, look at the second nugget of information.

4. Division. Similarly to the last function, this one also expects two values. Again, you need to do the comparison as the last time, but this time instead of printing the results, you need to choose the operands for the division operation.

Sample solution

NB! The sample has a visible debugging printout (starts with DEBUG). It’s recommended that you also do this to verify that you are indexing the array correctly. Once you are sure about your indexes and your code works, comment this out.

Testing

This is a partial list of the suggested tests:

  • Try a normal scenario that shouldn’t cause any errors.
  • Try out of bounds indexes ( -10, 10). Test them both as the first and the second index.
  • Try the out of bounds indexes multiple times to make sure that the program wouldn’t continue unless the inputs are usable.
  • Try indexes on the edge cases. E.g.
    • If you count from 0 – 6, try -1, 0, 6, 7
    • If you count from 1 – 7, try 0, 1, 7, 8
  • Try all 3 different results for comparison (<, >, ==)
  • Try to divide by zero. NB! Dividing by 0 is undefined! Just doing the division by zero may crash the program or reset the entire computer (it’s common for controllers to completely reset themselves if this happens). You are not allowed to perform divisions by zero!

Extra task 1 [W6-03]: Non-recurrent numbers

This is a continuation of lab task #1.

Requirements
  • Task must be built on the same base as the base task. The functionality of the base task must remain the program.
  • Create a new array based on the entered numbers. The new array must be built in a way that only a single instance of each number can exist in it.
  • Create functions as seem suitable for solving this task.
Testing

Extra task 2 [W6-04]: Additive inverses

This is a continuation of lab task #1.

Requirements
  • Task must be built on the same base as the base task. The functionality of the base task must remain the program.
  • Find and display the additive inverses of the numbers in the array.
  • Same numbers can be used in a pair only once, regardless of their ordering or repetition count.
  • Create functions as seem suitable for solving this task.
Testing

Make sure that the pairs don’t repeat.

After the class, you should

  • Know how to pass text (strings) into functions.
  • Know how and when to pass either the entire array or just a member from an array to a function.
  • Know and be able to compose and use arrays where not all members from the declared array are in use.
  • Be more comfortable indexing an array in other ways than from first to last element.
  • Be able to copy values from one array to another using two different indexes in the same loop.

PR1EN5: Arrays

Lab content

Tasks

The task for this week is separated into two parts. First complete the first part and present your solution. Then improve your existing solution by solving the second part of the task and present the solution again. The base task can be extended by two extra task.

Task 1 part 1 [W05-1]: Finding extreme values

Part 1 will be solved as a UML activity diagram in the class. You will have to implement the algorithm as a program based on the starter code presented, following the logic of the algorithm. In part 1, you will have four functions besides main() !

Download the starter code: https://blue.pri.ee/ttu/files/iax0583/aluskoodid/5_minmax_template.c

Requirements
  • Part 1 must match the logic described in the UML activity diagram
  • You have to complete all 4 functions that are described in the starter code as comments and use them in your solution. You will need to also add missing parts like macros, variable declarations, function prototypes and function calls.
  • User will enter 6 numbers from the keyboard, which will be stored in an array.
  • The process of entering the numbers must be clear. You must show which number and out of many they are currently entering
  • You need to find and print the smallest number in the array. The smallest value needs to be found in a user-defined function, returned and printed in main().
  • You need to find and print the greatest number in the array. The greatest value needs to be found in a user-defined function, returned and printed in main().
  • You need to print out the original array. This must be done in a separate function.
Workflow guide

NB! For every function, first read the function comment to understand what the function does, which inputs are needed as parameters and what the result (return) has to be. Each function must be implemented below the comment.

  1. Start by completing ReadIntArray()  function given in the starter code. This is the first function after main() .
    You will need to write a loop that on each iteration, prints the prompt and then reads the value, storing it into the array.  There will be a very similar example done in the lab as live code.
  2. To test it, we need to call the function. For this, we need to declare the array in the main function and then call the function, passing it the array and its length.
    Assuming you have a macro called NUM_CNT  and an array called numbers , the function call will look like  ReadIntArray(numbers, NUM_CNT); Test and see if your reading code works.
  3. To validate our results, we should print what we got.  Complete the function PrintArray()  and call it from main() .  Note that this time you have to set the parameters and return value yourself.
  4. Now you have two more functions to complete. Both are specified as function comments in the starter code. Finish the functions, call them out and print the results.
    NB! The functions finding min and max values are not allowed to have side effects. Results must be printed in the main() function.
Testing

Test 1: min first, max last

Test 2: min last, max first

Test 3: Min value is negative. Both min and max are in the middle of the array.

Task 1 part 2 [W05-2]: positions and repetition count

In part 1 you found the extreme values from the array. In part 2, you need to find the positions of those values and how many times they occurred.

Requirements
  • Print all positions of the greatest value in the array. Printing must be done in a separate function, outside of main() .
  • Print all positions of the smallest value in the array. Printing must be done in a separate function, outside of main() .
  • Print how many occurrences the min and max value had. Results must be found in a separate function and printed out in main() .
  • Positions printed must match the way you asked the user for input!
  • Implement the two functions specified under Workflow Guide. Reuse the created functions for both min and max values.
Workflow guide

To solve this part of the task, you need to create two functions. Both functions are given to you as function comments. You will need to implement the functions based on the comment.

First function will be to print out all the positions of the array. To do this, you need to loop through the array and every time you find the  number you are searching for (e.g. min value), you need to print out the position you are currently at in the loop! So in total, the function will consist of a loop, a conditional statement and a print statement – that’s it!

You need to reuse this function for both min and max! Note that the text describing the results should be printed in main (i.e. “Min value position(s): “)

After implementing this function, check that the code works before proceeding to the next function!

The second function will be very similar to the first one. In this one, you need to count instead of print. Once finished, just return the result you counted and print it in main() .  There is no printing of the result in the function itself, i.e. function should have no side effects!

Testing

Test 1: only 1 occurrence of min and max

Test 2: Multiple occurrences of min and max

Extra task 1 [W05-3]: Statistics

In this extra task, we will calculate 3 more results from the data in the array.

Requirements

  • Implement 3 functions, that will find the sum, product and arithmetic
  • Calculating arithmetic mean should reuse the function to calculate sum so you wouldn’t copy-paste code
  • All 3 functions must use the array and the length of the array as their parameters
  • All functions must calculate the result and return the answer. Result must be printed out in main()
  • Display the arithmetic mean with 3 places after the comma
Testing

The biggest stumbling block in this task is getting the arithmetic mean correct. Let’s test it.

Extra task 2 [W05-4]: n numbers without VLA

To make the program a bit more useful, we’ll allow the user to enter the amount of numbers the program can work with.

NB! Even though most C compilers work with VLAs (variable length array), not all versions of the C standard define it as mandatory property of the C language. Depending on the compiler, it may fail to work.

In addition, there are also downsides to performance of VLAs, which make them less preferred in performance-oriented tasks. In short, VLAs translate to more complex assembly code which takes more CPU cycles to execute. In addition, if no other checks are performed, it is extremely easy to crash programs using VLAs (e.g. I want to enter 10 000 000 numbers).

Because of this, you are allowed to declare an array where the size is defined by another variable (e.g.  int numbers[numberCount]; , where numberCount  is a variable specified by the user during runtime). The universal solution based on the standard is by using dynamic memory allocation, but that is a topic for Programming 2.

For the purpose of this lab task, you will decide on a maximum size that the user can enter and use that as the upper bound. This means, that most likely there will be unused slots in the array. However since our program is small, this won’t cause us problems.

Note, that in general, use of VLAs is not forbidden in this course. The limitation is for this task.

Requirements
  • Allow the user to specify how many numbers they will be entering
  • Limit the program so that the user cannot enter a number greater than the size of the array defined.
  • Asking of the size from the user must be handled by a function you create for this task. The function will only be allowed to return if the input is within the specified limits.
    • Use parameters to specify the limits
    • The function you create should be reusable in other similar situations (but with different limits).
  • You can choose the “reasonable” size of the array yourself (e.g. 50 members).
  • Create error handling for situations where the user enters the array size which is either too big or small.
  • Usage of VLA (variable length array) is forbidden in this task!
  • NB! Make sure to update your coding style – variables cannot be written in the same style as macros!
Testing

Make sure to test the following

  • Minimal allowed number count.
  • Maximum allowed number count.
  • Number count that is different from the original task.

After the class, you should

  • Know how to perform type casting
  • Know about floating point precision and problems with it
  • Know how fixed point and floating point number representation works
  • Know about math library and how to use it, including how to set the compiler flag, if necessary
  • What an array is
  • How to declare an array
  • How to initialize arrays
  • How to index each member of the array
  • How to index through an array using loops
  • How to find the extreme values in an array
  • How to pass arrays to functions

Additional content

PR1EN3: Loops

Lab materials

Tasks

This lab has two base tasks for which you need to create a total of four separate programs. There are also two extra tasks, separate from the base tasks, that can be written as a single program.

Task 1 [W03-1]: Sum of 5 numbers

You are tasked with creating a program that will find the sum of five numbers entered by the user. The program must be created 3 times – one for each loop type. All 3 programs must do the exact same thing.

Requirements
  • Program asks the user for 5 integers
  • After every number, except the last one, the program prints the current subtotal
  • After the last number is entered, the program prints the final sum instead of the subtotal
  • Program must give a clear instructions to the user
  • You cannot have any magical numbers in your code
  • Design your program in a way that if you would need to do the same task for 10, 20 or even 1000 numbers, you will only need to change one number in your code. Test it before submitting – change that number to be 7 and see if your program still works and the output makes sense!
  • Create the same program using a while, do while and a for loop
Hints
  • Think carefully which variables you will need! Regardless of how many numbers you need to add up, the amount of variables should remain the same
  • It’s recommended to start counting loops from 0. This is because most things that are counted in the computer, start from 0. However you should display a number incremented by 1 to the user – non-developers usually count from 1.
    • (i + 1) takes the value if i and uses the incremented value in that place only. The incremented value is not stored and does not affect the program elsewhere.  E.g. printf("%d", i + 1);
    • Operations such as  i++, ++i, i += 1 and i = i + 1 store the updated value after incrementing (permanent).
Testing

This is the expected output of the program

Task 2 [W03-2]: Cash register with input validation

In this task, we will revisit the task from last week and add a few features to it. You can either use the provided starter code or your own solution from last week.

Download the lab task 2 starter code [optional]: https://blue.pri.ee/ttu/files/iax0583/aluskoodid/3_1_cashier_starter_loop.c

Requirements

You must add the following features to the program

1. Input validation for loyalty card and extra discount

  • Ask the user for input until either 0 or 1 is entered
  • For invalid input, print an error message
  • Recommendation: Use an exit-controlled loop.

2. PIN code can be entered up to 3 times

  • If the PIN code has been entered incorrectly for 3 times, write an error message and close the program.
  • If a correct PIN is entered within 3 attempts, check the balance and if possible, do the transaction.
  • Recommendation: Use an entry-controlled counting loop.
Testing

Extra tasks

Extra task 1 [W03-3]: Mario tower
  • Using nested loops, create a representation of the Mario stairs using the pound symbol. A total of 13 rows of steps.
  • Place an ASCII stick man on top of the stairs
  • The width of the top platform must be enough for the stick man to rest his feet comfortably
  • In the end of each row, show the number of blocks used for that row and the total number of used blocks until that moment
  • Alignment should be as shown in the example below
Extra task 2 [W03-4]: Mirrored tower with specified height
  • Ask the user for the width of the platform (range 7 -20 blocks)
  • The steps must be mirrored this time as is in the Mario game when approaching the castle.
  • The bottom-most step must start from the left edge of the terminal window, no spaces allowed before it.
Hints

After the class, you should

  • Know what steps need to be gone through to get from the source code that we write to a executable program
  • Know what is a #define macro and how it works
  • Know what is a magic number and how to handle them
  • Know about problems with non-initialized variables.
  • Use a switch statement.
  • Use all 3 types of loops for a specified number of iterations.
  • Know how to create a loop that runs infinitely
  • Know the increment/decrement operators.
  • Know the difference between loops that check the conditions before or after executing the loop body.
  • Be able to nest blocks of code (e.g. conditional statement inside of a loop, loop inside of a loop, …)
  • Know about two control statements: break and continue.
  • Know, that we DO NOT use goto statements.
  • Use expressions and constants as printf arguments.
  • Be able to model loops in UML

Additional content

PR1EN1: Hello world

Lab materials

Tasks

Most likely everything in this lab is completely new to you. Because of this, most of the lab we’ll be working together – lecturer shows things in front and you’ll follow along on your computer.

In the end of the lab, you’ll have one base task to complete and defend. Faster ones will also be able to complete and defend the extra task.

Task 1 [W01-1]: Parity check (base task)

Requirements
  • User is asked for and must be able to enter an integer
  • Program must prints the entered number
  • Program must print if the entered integer was odd or even

NB! In addition to functional requirements, the program  must also follow the style requirements. Most common errors are related to indentation (number of spaces from the left before the code), missing spaces surrounding operators (e.g. space before and after equal sign) and lack of empty lines to indicate different logical parts of the program.

Task background

Modulo division is widely used as a means of creating a checksum. E.g. it can be used to validate your Estonian ID code or bank card number.

In this task we are doing modulo 2 division – i.e. dividing the number by 2 and taking the remainder. This allows us to check if the number is odd or even. Parity check is one of the simplest ways to do error checking in data transfers – e.g. if the amount of bits in a data packet with the value ‘1’ is odd or even? This can be used to check if there was a data transmission error (though as said before, this will only catch extremely simple errors).

Pseudo code

Pseudo code is one way of describing algorithms. It uses similar structure to a program, but does not adhere to language specific rules such as syntax requirements. This means pseudo code is typically human readable without knowledge of programming.

Algorithm

The task is modeled together in a class, to show you some of the techniques around formatting the diagram – e.g. how to create a conditional statement, using right angles when creating control flows etc. For the sake of completeness of the task specification, we have also given one of the two possible forms of this algorithm in this page.

How to solve the task

When solving the task, follow both the algorithm and the code snippets provided on the slides. This task resembles a lego that needs to be assembled correctly.

  1. Start by creating a new file. Save it in a subdirectory for Programming course on your P drive using a   .c  file extension- e.g. paritycheck.c .
  2. Now write the template code from the last slide into your code file. We will be showing you this on the projector as well. Note that we have left a mistake in the template! You should immediately notice it if you try to compile the program at its current state. Fix the mistake before proceeding to work on the task. If necessary, look in your hello.c  program for a similar line – you should find a solution and explanation in the comment of your code.
  3. The next piece of the puzzle is the code structure for a conditional statement. Find how to find the conditional if/else statement from the slides and write the structure into your program. Don’t copy code – writing helps with your muscle memory. Make sure to pay attention to the indentation of the code and the space following the  if keyword. Poorly formatted code will not pass the defense.
  4. Third piece of the puzzle is the condition itself (goes within the parenthesis for the  if  statement. Just as a reminder, the task is to check if an entered number is odd or even. Examples of conditions are provided on the slides. After creating the conditional statements, try to compile and make sure there are no errors!
  5. The last piece of the puzzle is the contents for the code blocks so that the result would be printed correctly. For this you need to write two calls to the  printf()  function. They should look something similar to the following code statement:
    Notice, that we left in two blanks. One of them needs to contain the number entered by the user. The second one whether it was an odd or an even number.
Testing

This program has two possible outcomes – the number is either even or odd. To test your program, you need to run the program twice, covering both of these tests.

Test 1: even number

Test 2: odd number

Everything worked as intended? Good, you are almost done!

Remember that the code has to be readable and maintainable. To achieve this, all programmers must adhere to coding style. Compare the look of your code to previous programs and examples from this class. Pay attention to

  • Use of spaces (before and after mathematical operators, after the if  keyword
  • Indentation – how many spaces must be left empty from the left of the text document on each line. Indentation by 1 is typically considered to be 1 tab or 4 spaces. The statements inside of a code block (indicated by the curly braces) always increase indentation by 1. This means that the code in the main function should be indented one (e.g. asking for input, reading input, return statement), but the printing of the result should be indented once more, because they are inside of another (nested) code block.
  • Use empty lines to visually separate different parts of code (before main()  function, before the if  statement, before the return statement)

Code both functional and readable? Now let us know that you want to defend your task!

Extra task [W01-2]: Division by 3 and 5

Before solving this task, solve the base task! You should first defend the base task and then the extra task.

Read on how to use logical operators: https://blue.pri.ee/ttu/coding-guides/conditional-statements/#Logical_operators

Requirements
  • User is asked for and must be able to enter an integer
  • Program must print whether the entered number is divisible by 3, divisible by 5, divisible by both or neither of them.
  • The program must find the multiples and remainders by dividing the number by both 3 and 5. All four results must be printed regardless of the divisibility.
  • Calculations (e.g. divisions) can only be done once. If you need to use the result multiple times in your code, store it in a variable.
Background

The task is based on a classical interview question used for recruiting software developers. This is a modified version of the FizzBuzz task.

Testing

Based on the divisibility checks, you have 4 possible outcomes that must all be tested.

Test 1: Number is divisible by both 3 and 5

Test 2: Number is divisible by 3 only

Figure the last 2 tests out on your own and make sure it works in all cases!

After this class, you should

  • Understand the requirements for this subject, including how to get a grade
  • Be able to log into Linux on the class computer
  • Know the main software we use in this class
  • Know your way around the environments – where to find what
  • Know what is the C programming language, how does the program structure look like and how to write a basic program.
  • Know the structure of a C program and be able to write, compile and execute a simple program.
  • Understand the basics of the following programming concepts.
    •  #include statements
    • why is main() function special
    • declaring variables, data types
    • print statements for basic text, changing line, printing the contents of a single or multiple variables with text and integer data types.
    • reading a value from keyboard and storing it in a variable (scanf statement)
    • basic math operations and how they are written
    • if/else statement (conditional statement)
    • Understand integer division and modulo division
  • Understand what an algorithm is
  • Understand what is UML and why it is used. Understanding the basic elements (start, end, action statement, fork, join) in the design. Being able to create a basic diagram in UML.

Additional content