# Ex W3

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.

Tips:

• use a `std::vector<std::vector<std::string>>` and initialize it with the 5 lines representing each digit, e.g., use `" - ", "| |"` for the first two rows of digit zero. The "outer" vector contains 10 digits and the inner vector the representation of each digit (the five lines).
• Can you minimize the use of hand-written loops? Note: `printLargeDigit` can be solved without custom loops.
• Show your solution as early as possible to your supervisor for feedback.
• Work in small teams (up to 3) to speed up your programming time and increase your result quality.
• Getting this working together with appropriate unit tests is important, since you need the solution for your testat exercise next week.
• You won't be able to use `printLargeDigit` to implement `printLargeNumber`.

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.

 Last edited October 23, 2018