go to start Ex W3
|home |print view |recent changes |changed October 23, 2018 |
|You are <- set your identity!

Sections: Simulated 7-Segment Display for Numbers | Counting again - without loops | Count non-whitespace char | Count all characters | Count words | Count 'a's | Count lines | Extra exercises for self-study (Optional) | Scaleable 7-Segment Digit Number Display | Sum numbers | Multiplication table | Decimal Fractions |

In this week, we will start with an exercise that will be combined into a hand-in next week (Testatabgabe).

However, to get into the mood of programming you might start with the simpler counting exercises first. But those shouldn't take too long to solve. If you find you are too slow, there is only one remedy: exercise exercise exercise... OTOH, if you are stuck during the exercise lesson, do not just wait until your supervisor shows up at your place, but actively seek support, either by him or by your fellow students.

If your workspace accumulates too many projects and you loose the overview on what you are working on, close the old projects and hide the closed projects from the workspace using the workspace preferences or define working sets in the project view (little triangle button).

Simulated 7-Segment Display for Numbers ^

This exercise will be part of the "Testat" hand in.

Create a function printLargeNumber(int i, std::ostream &out) that allows you to output a large number on a simulated 7-segment digits display. We will use that function later on for the Testat. For example, the number 1234567890 should be output as

    -  -     -  -  -  -  -  - 
  |  |  || ||  |    || || || |
    -  -  -  -  -     -  -    
  ||    |  |  || |  || |  || |
    -  -     -  -     -  -  - 
To achieve that goal, first start with a function printLargeDigit(int i, std::ostream &out) to print such a single large digit given by a number. printLargeDigit(int i, std::ostream &out) will produce a simulated 7-segment-digit for the numbers 0,1,2,...,9 given as parameter i.

Provide unit tests for the output of that number. An example output for the digit 8 looks as follows:

| |
| |

For the "production code" of printLargeDigit and printLargeNumber, create a separate library project with a header declaring the function(s) and an implementation file for their implementation. Note that you should minimize dependencies to other files, even the standard library, in header files.


For unit testing your functions you can rely on string splicing to have a nice representation of the expected result. String splicing combines (splices) adjacent string literals at compile-time to single string literal. Example test case:

void testPrintLargeDigitZero() {
  std::ostringstream output{};
  printLargeDigit(0, output);
  ASSERT_EQUAL(" - \n"
               "| |\n"
               "   \n"
               "| |\n"
               " - \n", output.str());

Note for 2019: State clearly that negative Numbers should be printed as well! Hand-in must include both: printLargeDigit and printLargeNumber.

Counting again - without loops ^

This week we repeat some of the exercises of last week. However, now you need to solve the task without writing a loop of your own, but by using iterators and algorithms of the standard library. One function you might need to know about is std::distance() that takes two iterators forming a range and returns the number of elements in that range. Using distance is convenient for counting all elements in a range.

If you are unsure about the correct solution, start out with encapsulating it in a function and write unit tests first using std::stringstream objects as input and output substitutes. Create all solutions by using algorithms instead of loops. If you can not achieve that, please ask your supervisor for tips.

Count non-whitespace char ^

Write a program chcount to count non-whitespace char values by reading from standard input with an std::istream_iterator. The result should be printed on standard output.

Count all characters ^

Modify your program to chacount that can count all characters on standard input including white-space. You might need to use a std::istreambuf_iterator that reads all characters on the input.

Can you think of other means to achieve that?

Count words ^

Write a program wcount to count words separated by whitespace characters by reading from standard input. The result should be printed on standard output. A word should be defined by what the input operator>> decides to be read as a std::string. Use an iterator and std::distance() to calculate the result.

Compare the output of your wcount program with the unix command wc on some large text file.

Count 'a's ^

Write a program acount to count the occurrences of the letter 'a' by reading from standard input. The result should be printed on standard output. Use a corresponding algorithm to achieve your solution without further loops or conditional statements in your program.

Count lines ^

Write a program lcount that counts the number of lines available on standard input. The result should be printed on standard output. You can do so, by matching the newline character '\n'. Do not write a loop, use a standard algorithm to determine the number. Compare your output with the result of the wc -l command on a large text file.

Extra exercises for self-study (Optional) ^

Scaleable 7-Segment Digit Number Display ^

Vary your functions from above so that they take an additional parameter: a scaling factor n. The digit(s) are scaled, by repeating the middle character of each line n times and by repeating the 2nd and 4th row of the unscaled digit n times. The number 8 scaled by factor 2 looks like this:

|  |
|  |
|  |
|  |
To avoid duplicating code and because we do not have classes yet, you can define the shared data structure with the solution above as a global constant (which is not as poisonous as a global variable).

Note: this exercise allows hand-written loops for the scaling. But you can try to find a solution with as few loops as possible. Maybe, you can experiment to create a solution that relies on algorithms only.

Sum numbers ^

Write a program sumi to sum up a sequence of integer numbers given on standard input. Assume only numbers separated by whitespace are given. Print the resulting sum on standard output. Do not use a loop. How much would need to change to sum floating point numbers instead? Do so but in a separate program called sumd

Multiplication table ^

Write a program multab to print a multiplication table for the integers from 1 to 20. Start by filling a std::vector<int> with the numbers 1 to 20. You shouldn't use a loop to create the table, therefore you might need to nest algorithm calls in a lambda expression or function call to get the nested iteration. The output can be generated onto an std::ostream_iterator with an algorithm that 'transforms' its input.

Note: use a lambda with capture by reference:

[&](auto x){...}

Decimal Fractions ^

Can you vary your program multab to print a table of decimal fractions (fractab) for a divided by b, where a and b take the range from 1 to 10? Also without any self-made loops.

|home |print view |recent changes |changed October 23, 2018 |
|You are <- set your identity!

Ex W3
go to start