# Solutions

## Lunar lander control

:::{solution} which-are-statements
1. [x] `air_conditioner = 1;`
1. [x] `if (...) else ...`
1. [ ] `a > b`
1. [ ] `5`
1. [x] `success = a > b;`
:::

::::{solution} lunar-lander-control-code
:::{literalinclude} solutions/LunarLanderControl.cs
:language: csharp
:::
::::

## Conveyor belt capacity check

:::{solution} conveyor-belt-capacity-check-flowchart
```{mermaid}
flowchart TD
    a["`prompt for *motor count*`"] -->
    b["`prompt for *package weight*`"] -->
    c{"`is *package weight per motor* less or equal than 5.6?`"}

    c -- true --> d["`output *carrying is possible*`"]
    c -- false --> e["`output *carrying is not possible*`"]
```
:::

:::{solution} array-or-not
1. [ ] `int array = 5`{l=cs}
1. [x] `string[] choices = ["black bird", "great tit", "falcon"]`{l=cs}
1. [ ] `int[] part_ids= [3093, -49318, 3092.8];`{l=cs}
1. [x] `string[] names = []`{l=cs}
:::


::::{solution} conveyor-belt-capacity-check-try-again
:::{literalinclude} solutions/ConveyorBeltCapacityCheck.cs
:language: csharp
:::
::::

## Spare parts inventory assistant

:::{solution} data-logic-separation
1. - left code is shorter, because it does not use the variables used in the right. It looks more readable on the first sight.
   - right code separates *control flow* from the *data*. Data are the messages shown to the user.
2. - If there is no separation, the long sentences may distract the programmer from the actual control flow logic and vice-versa.
   - If there is separation, then the data can be more conveniently modified. 
   - this structure allows for adapting data without modifying the control flow, which is useful for, e.g., translation
:::

:::{solution} ternary-conditional-operator-conversion
```cs
// Assume values 
var altitude = 20;
var thruster = true;

var behaviorCorrect = (altitude > 100 && !thruster) ||
                      (altitude is <= 100 and > 0 && thruster) ||
                      (altitude <= 0 && !thruster);
if (behaviorCorrect)
    Console.WriteLine("✅");
else
    Console.WriteLine("❌");
```
:::

:::{solution} bool-expr-which-false

1. [x] `t == f`{l=cs}
2. [ ] `t = f`{l=cs}
3. [x] `i >= c && i > k`{l=cs}
4. [x] `!t`{l=cs}
5. [ ] `k != 2`{l=cs}
6. [ ] `10 < c || c <= 20`{l=cs} 
:::

::::{solution} spare-parts-inventory-assistant-try-again
Without separation of data and logic
:::{literalinclude} solutions/SparePartsInventoryAssistant-without-data-logic-separation.cs
:language: csharp
:::

With separation:
:::{literalinclude} solutions/SparePartsInventoryAssistant-with-data-logic-separation.cs
:language: csharp
:::
:::{card} For the curious
You see that the array `userQuestions` is not annotated with `const`, even we use it as a constant. An array cannot be constant in C#, because arrays must be initialized at runtime. Moreover: [collection expressions](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/collection-expressions) are executed at runtime.
> You can't use a collection expression where a compile-time constant is expected, such as initializing a constant, or as the default value for a method argument.
:::
::::

## Currency converter with GUI

:::{literalinclude} code-wi/CurrencyConverterWithGui/MainWindow.axaml
:language: xml
:::
:::{literalinclude} code-wi/CurrencyConverterWithGui/MainWindow.axaml.cs
:language: cs
:::

## RPSSL

:::{solution} rpssl-continued
```{literalinclude} code-wi/Rpssl/MainWindow.axaml
:language: xml
```
```{literalinclude} code-wi/Rpssl/MainWindow.axaml.cs
:language: cs
```
:::

## Inventory system

- <repo-download-prj:InventorySystem>
- <repo-browse-prj:InventorySystem>

## Item sorter robot

- <repo-download-prj:ISv2SorterRobot>
- <repo-browse-prj:ISv2SorterRobot>

:::{solution} waving-robot-arm
```{literalinclude} code/waving-robot-arm.script
:language: python
```
:::

:::{solution} finding-a-position-in-a-coordinate-frame
[0, -.5, 0]. Actually every position with z=0, but the tool cannot always reach every z=0, because it has limits.
:::

:::{solution} finding-a-feasible-pose-for-the-robot
All other than 3. could be used for picking an object. The video shows only from the top, but the items could be also gripped from the side.

We see that all poses other than 3 rotate 90 and 180 degrees around the x and y axes, which turns the gripper into a feasible position. Note that if y is not large or small enough, these poses will not work.
:::

:::{solution} moving-between-points-on-a-coordinate-system
```{literalinclude} code/moving-between-points-on-a-coordinate-system.script
```
:::

## Item sorter robot – real

- <repo-download-prj:ISv3RealRobot>
- <repo-browse-prj:ISv3RealRobot>

:::{solution} isv3-required-modifications
1. Gripper functionality
1. GUI changes for IP address configuration
:::

## Review problems 2

:::{solution} operator-precedence-mc
4, 6
The most readable solution would be:

```cs
a * Math.Pow(x, 3) + (c - 1) * x + d
```
:::

:::{solution} coding-a-mathematical-formula
```{literalinclude} code/coding-a-mathematical-formula.cs
:language: cs
```
:::

:::{solution} processing-invalid-user-input
```{mermaid}
flowchart TD
s(start)
a[ask for `a` and store user input]
r{{is user input a valid decimal number?}}
b[ask for `b` and store user input]
tryAgainMsg[Communicate that the user should try again]
repeat[... ]
calculate[calculate and output `y`]
e(end)

s --> a --> r -->|yes| b --> repeat --> calculate --> e
r -->|no| tryAgainMsg --> a
```

```{literalinclude} code/processing-invalid-user-input.cs
:language: cs
```
:::