mirror of https://github.com/01-edu/public.git
DEV-3951-calculator (#1706)
* 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 file
This commit is contained in:
parent
01857cd9cc
commit
dc8002d92e
|
@ -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