mirror of https://github.com/01-edu/public.git
Browse Source
* feat(calculator): add new exercise to scripting piscine * test(calculator): fix swapped exit codes for error handling * docs(calculator): clarify function behavior for errors * test(calculator): update error message for invalid number * docs(calculator): add explicit case statement requirement improve references section style add case and getent examples * fix(calculator): remove getent info in the subject * chore(calculator): make the solution executable * test(calculator): add check for case usage * test(calculator): fix case statement usage check on wrong file * fix(calculator): remove script added by error revert changes committed by mistake on Dockerfile and entrypoint.sh * style(calculator): add newline at end of filepull/1739/head
Michele
2 years ago
committed by
GitHub
3 changed files with 248 additions and 0 deletions
@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash |
||||
|
||||
# set -euo pipefail |
||||
IFS=' |
||||
' |
||||
|
||||
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd) |
||||
|
||||
challenge() { |
||||
submitted="./calculator.sh $@ |
||||
" |
||||
expected="./calculator.sh $@ |
||||
" |
||||
submitted+=$(2>&1 bash "$script_dirS"/student/calculator.sh "$@") |
||||
submitted+=" |
||||
exit status: $?" |
||||
expected+=$(2>&1 bash "$script_dirS"/solutions/calculator.sh "$@") |
||||
expected+=" |
||||
exit status: $?" |
||||
|
||||
diff -U 1 <(echo "$submitted") <(echo "$expected") |
||||
if [ $? != 0 ] |
||||
then |
||||
exit 1 |
||||
fi |
||||
} |
||||
|
||||
# Check if student uses case statement |
||||
if [[ $(cat "$script_dirS"/student/calculator.sh | grep case | wc -l) -eq 0 ]] |
||||
then |
||||
echo "Error: the use of case statement is mandatory" |
||||
exit 1 |
||||
fi |
||||
|
||||
# Valid inputs |
||||
challenge "15" "+" "10" |
||||
challenge "15" "-" "10" |
||||
challenge "15" "/" "10" |
||||
challenge "15" "*" "10" |
||||
|
||||
challenge "3491" "+" "-67" |
||||
challenge "3491" "-" "-67" |
||||
challenge "3491" "/" "-67" |
||||
challenge "3491" "*" "-67" |
||||
|
||||
challenge "-3491" "+" "-67" |
||||
challenge "-3491" "-" "-67" |
||||
challenge "-3491" "/" "-67" |
||||
challenge "-3491" "*" "-67" |
||||
|
||||
# Invalid inputs |
||||
|
||||
challenge |
||||
challenge "-3491" "*" "-67" "10" "12" |
||||
|
||||
challenge "20" "/" "0" |
||||
challenge "20" "@" "10" |
||||
challenge "10" "*" "67invalid" |
||||
|
||||
# Test operators functions |
||||
|
||||
source $script_dirS"/student/calculator.sh" 10 + 10 >/dev/null 2>&1 |
||||
|
||||
if [ $(do_add 11 14) != 25 ] |
||||
then |
||||
echo "error in function do_add" |
||||
exit 1 |
||||
fi |
||||
|
||||
if [ $(do_sub 11 14) != -3 ] |
||||
then |
||||
echo "error in function do_sub" |
||||
exit 1 |
||||
fi |
||||
|
||||
if [ $(do_mult 3 5) != 15 ] |
||||
then |
||||
echo "error in function do_mult" |
||||
exit 1 |
||||
fi |
||||
|
||||
if [ $(do_divide 50 5) != 10 ] |
||||
then |
||||
echo "error in function do_divide" |
||||
exit 1 |
||||
fi |
@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env bash |
||||
|
||||
# Unofficial Bash Strict Mode |
||||
set -euo pipefail |
||||
IFS=' |
||||
' |
||||
|
||||
number='^-?[0-9]+$' |
||||
|
||||
do_add () { |
||||
echo $(($1 + $2)) |
||||
} |
||||
|
||||
do_sub () { |
||||
echo $(($1 - $2)) |
||||
} |
||||
|
||||
do_mult () { |
||||
echo $(($1 * $2)) |
||||
} |
||||
|
||||
do_divide () { |
||||
echo $(($1 / $2)) |
||||
} |
||||
|
||||
|
||||
if [ $# != 3 ] |
||||
then |
||||
>&2 echo "Error: expect 3 arguments" |
||||
exit 1 |
||||
elif ! [[ $1 =~ $number && $3 =~ $number ]] |
||||
then |
||||
>&2 echo "Error: invalid number" |
||||
exit 4 |
||||
else |
||||
case $2 in |
||||
|
||||
"+") |
||||
echo $(do_add $1 $3) |
||||
;; |
||||
|
||||
"-") |
||||
echo $(do_sub $1 $3) |
||||
;; |
||||
|
||||
"*") |
||||
echo $(do_mult $1 $3) |
||||
;; |
||||
|
||||
"/") |
||||
if [ $3 == 0 ] |
||||
then |
||||
>&2 echo "Error: division by 0" |
||||
exit 2 |
||||
fi |
||||
echo $(do_divide $1 $3) |
||||
;; |
||||
|
||||
*) |
||||
>&2 echo "Error: invalid operator" |
||||
exit 3 |
||||
;; |
||||
|
||||
esac |
||||
|
||||
fi |
@ -0,0 +1,96 @@
|
||||
## Calculator |
||||
|
||||
### Instructions |
||||
|
||||
In this exercise you will make a script `calculator.sh` that will take 3 arguments, calculate the result and print it on the standard output. |
||||
|
||||
- The first argument and the third argument will be numbers. |
||||
- The second argument will be the operator. |
||||
|
||||
Each operator should have its own function named as follow: |
||||
- `+`: `do_add()`. |
||||
- `-`: `do_sub()`. |
||||
- `*`: `do_mult()`. |
||||
- `/`: `do_divide()`. |
||||
|
||||
Each function will receive two arguments, the left number and the right number, and return the result of the operation. |
||||
|
||||
The functions assume that the input is valid, so the input must be checked before calling the functions. |
||||
|
||||
To choose which function to call you must use the `case` statement. |
||||
|
||||
> The functions will also be tested individually, so it is important to name each function exactly as above, the behavior of the functions have to match the exercise instructions. |
||||
|
||||
### Usage |
||||
|
||||
```console |
||||
$ ./calculator.sh 20 "*" 3 |
||||
60 |
||||
$ ./calculator.sh 20 / 20 |
||||
1 |
||||
$ ./calculator.sh -1 - 10 |
||||
-11 |
||||
$ |
||||
``` |
||||
|
||||
### Error handling |
||||
|
||||
All errors will print a specific message on **stderr** (ending with a newline) and returns a specific non-zero value: |
||||
- Wrong number of arguments: `"Error: expect 3 arguments"`, returns `1`. |
||||
- Division by 0: `"Error: division by 0"`, exit with `2`. |
||||
- Invalid operator: `"Error: invalid operator"`, exit with `3`. |
||||
- Invalid number(s): `"Error: invalid number"`, exit with `4`. |
||||
|
||||
> Negative numbers are also a valid input. |
||||
|
||||
### Hints |
||||
|
||||
- `case` statement example: |
||||
```sh |
||||
# Check the first argument given to a script |
||||
case $1 in |
||||
"left") |
||||
echo "We will turn left" |
||||
;; |
||||
|
||||
"right") |
||||
echo "We will turn right" |
||||
;; |
||||
|
||||
"top") |
||||
echo "We will turn top" |
||||
;; |
||||
|
||||
"bottom") |
||||
echo "We will turn bottom" |
||||
;; |
||||
|
||||
# Any other case |
||||
*) |
||||
# This is printed in stderr |
||||
>&2 echo "Error: invalid argument" |
||||
exit 2 |
||||
;; |
||||
esac |
||||
``` |
||||
|
||||
- Example of a function taking two arguments and returning a value by printing it. |
||||
The behavior of this function is the same than the one expected for the operators functions you will create: |
||||
```sh |
||||
print_full_name () { |
||||
name=$1 |
||||
surname=$2 |
||||
echo $name $surname |
||||
} |
||||
|
||||
print_full_name "Gene" "Mallamar" |
||||
``` |
||||
|
||||
> Google and Man will be your friends! |
||||
|
||||
### References |
||||
|
||||
- [Bash functions](https://linuxize.com/post/bash-functions/) |
||||
- [Test if a variable is a number](https://stackoverflow.com/questions/806906/how-do-i-test-if-a-variable-is-a-number-in-bash) |
||||
- [Print on standard error](https://stackoverflow.com/questions/2990414/echo-that-outputs-to-stderr) |
||||
- [Case statement](https://linuxize.com/post/bash-case-statement/) |
Loading…
Reference in new issue