I’m having trouble getting this one to pass on the task: If you pick a service that doesn’t exist, you should be shown the same list of services again.
The code works, I’ve tested it against the examples.txt
I am not following the same procedure as the bike rental:
I’m getting the available options from the SQL, and check if they fit.
Relevant part of salon.sh:
OPTIONS=$($PSQL "SELECT service_id, name FROM services ORDER BY service_id")
echo "$OPTIONS" | while read SERVICE_ID BAR NAME
do
echo "$SERVICE_ID) $NAME"
done
read SERVICE_ID_SELECTED
if [[ ! $SERVICE_ID_SELECTED =~ ^[0-9]+$ ]]
then
# send to main menu
MAIN_MENU "I could not find that service. What would you like today?"
fi
#check if service exists
SERVICE_ID_EXISTS=$($PSQL "SELECT service_id FROM services WHERE service_id=$SERVICE_ID_SELECTED")
if [[ -z $SERVICE_ID_EXISTS ]]
then
#if not go to main menu
MAIN_MENU "I could not find that service. What would you like today?"
else
#....rest of the code
It does exactly as it should.
If you answer non-numeric, it fails the regex bit, and goes to main menu.
If the answer is not between 1 and 5 (both included) it fails the second part(service_id_exists) and goes to main menu.
That’s why I don’t understand why it fails this test…
#!/bin/bash
PSQL="psql --username=freecodecamp --dbname=salon --tuples-only -c"
echo -e "\nWelcome to Metworst Salon, how can I help you?\n"
MENU() {
if [[ $1 ]]
then
echo -e "\n$1"
fi
#list services
OPTIONS=$($PSQL "SELECT service_id, name FROM services ORDER BY service_id;")
echo "$OPTIONS" | while read SERVICE_ID BAR NAME
do
echo "$SERVICE_ID) $NAME"
done
#select service, if empty back to menu
read SERVICE_ID_SELECTED
if [[ -z $SERVICE_ID_SELECTED || ! $SERVICE_ID_SELECTED =~ ^[0-9]+$ ]]
then
MENU "I could not find that service. What would you like today?"
fi
#check if service exists, if not send back to menu
SERVICE_AVAILABLE=$($PSQL "SELECT service_id FROM services WHERE service_id=$SERVICE_ID_SELECTED")
if [[ -z $SERVICE_AVAILABLE ]]
then
MENU "I could not find that service. What would you like today?"
fi
#get phone number
echo -e "\nWhat's your phone number?"
read CUSTOMER_PHONE
#check if already customer
CUSTOMER_ID=$($PSQL "SELECT customer_id FROM customers WHERE phone='$CUSTOMER_PHONE';")
#if not get name
if [[ -z $CUSTOMER_ID ]]
then
echo "I don't have a record for that phone number, what's your name?"
read CUSTOMER_NAME
#enter customer in dbase
INSERT_CUSTOMER_RESULT=$($PSQL "INSERT INTO customers(name, phone) VALUES('$CUSTOMER_NAME','$CUSTOMER_PHONE');")
fi
#get time
SERVICE_NAME=$($PSQL "SELECT name FROM services WHERE service_id=$SERVICE_ID_SELECTED")
SERVICE_NAME_CUT=$(echo $SERVICE_NAME | sed 's/ |/"/')
CUSTOMER_NAME=$($PSQL "SELECT name FROM customers WHERE phone='$CUSTOMER_PHONE'")
CUSTOMER_NAME_CUT=$(echo $CUSTOMER_NAME | sed 's/ |/"/')
echo -e "\nWhat time do you want your $SERVICE_NAME_CUT, $CUSTOMER_NAME_CUT?"
read SERVICE_TIME
#add in dbase and show appointment
CUSTOMER_ID=$($PSQL "SELECT customer_id FROM customers WHERE phone='$CUSTOMER_PHONE';")
SERVICE_TIME_ADDED=$($PSQL "INSERT INTO appointments(customer_id, service_id, time) VALUES($CUSTOMER_ID, $SERVICE_ID_SELECTED, '$SERVICE_TIME');")
echo -e "\nI have put you down for a $SERVICE_NAME_CUT at $SERVICE_TIME, $CUSTOMER_NAME_CUT."
} #end menu
MENU
So this is what I found out myself:
It works, it does what is asked.
All the tests pass, except If you pick a service that doesn’t exist, you should be shown the same list of services again
However, if I comment out line 46 (read SERVICE_TIME) the above test passes.
Further down a few fail, but that is to be expected with a missing variable.
sorry i am finding the code hard to read because of the weird indentation used.
Anyway, I suspect the problem has to do with the way you call back the MENU function when something goes wrong but also after calling it back, when it ends, the rest of the lines of code will run.
So if someone enters
10
you call MENU
then if they type
10 again
you call MENU
then if they type
10 again
you call MENU
then if they type 2 which is correct
then your code runs but after it gets to the last line of the last MENU call it returns
back to continue the previous call , and the previous call and the previous call
(like a recursive execution, it ends but then the remaining code runs).
I would split off the part that takes the user selection away from the part that runs when the user selection is correct.
(for eg. make another function BOOK for example to perform the code that runs after the selection is verified)
That way all the the recursive calls to MENU are contained within MENU
and the booking part only happens once.