Salon appointment scheduler, show same list of services again test not passing

Hello, sorry for the repeated question but a few people seem to have had issues with this test and none of the threads about it include a solution.

I have passed every test except the one which states: ‘If you pick a service that doesn’t exist, you should be shown the same list of services again’.

I did include this function in my script and it works as specified when I test it. See below my code:

> #! /bin/bash
> PSQL="psql -X --username=freecodecamp --dbname=salon --tuples-only -c"
> 
> echo -e "\n~~~~~~~~~~Hairdresser's~~~~~~~~~~\n"
> 
> MENU()
> {
>   echo -e "\nWelcome to the hairdresser's. Take a look at our services:\n"
>   # get services
>   SERVICES=$($PSQL "SELECT service_id, name FROM services ORDER BY service_id")
>   # display services
>   echo "$SERVICES" | while read SERVICE_ID BAR SERVICE
>   do
>     echo -e "$SERVICE_ID) "$SERVICE""
>   done
>   echo -e "\nWhich service would you like today?"
>   GET_DETAILS
> }
> 
> GET_DETAILS()
> {
> read SERVICE_ID_SELECTED
> # get service
> SELECTED_SERVICE=$($PSQL "SELECT service_id FROM services WHERE service_id = $SERVICE_ID_SELECTED")
> # if service doesn't exist
> if [[ -z $SELECTED_SERVICE ]]
> then
>   # send to main menu
>   echo -e "\nThat is not a valid service."
>   MENU
> else
>   # get phone number
>   echo -e "\nWhat is your phone number?"
>   read CUSTOMER_PHONE
>   # if customer doesn't exist
>   EXISTING_CUSTOMER_NAME=$($PSQL "SELECT name FROM customers WHERE phone = '$CUSTOMER_PHONE'")
>   if [[ -z $EXISTING_CUSTOMER_NAME ]]
>   then
>     # get customer name
>     echo -e "\nIt seems you have not visited us before. Welcome! What is your name?"
>     read CUSTOMER_NAME
>     # insert customer
>     INSERT_CUSTOMER_RESULT=$($PSQL "INSERT INTO customers(name, phone) VALUES('$CUSTOMER_NAME', '$CUSTOMER_PHONE')")
>   else
>   EXISTING_CUSTOMER_NAME_FORMATTED=$(echo $EXISTING_CUSTOMER_NAME | sed -r 's/^ *| *$//g')
>     echo -e "\nWelcome back, $EXISTING_CUSTOMER_NAME_FORMATTED." 
>   fi
> fi
> MAKE_APPO
> }
> 
> MAKE_APPO()
> {
> echo -e "\nWhat time would you like to come in?"
> read SERVICE_TIME
> # get customer_id
> CUST_ID=$($PSQL "SELECT customer_id FROM customers WHERE phone = '$CUSTOMER_PHONE'")
> # add appointment
> ADD_APPO_RESULT=$($PSQL "INSERT INTO appointments(customer_id, service_id, time) VALUES($CUST_ID, $SELECTED_SERVICE, '$SERVICE_TIME')")
> # get service name
> SERVICE_NAME=$($PSQL "SELECT name FROM services WHERE service_id = $SELECTED_SERVICE")
> SERVICE_NAME_FORMATTED=$(echo $SERVICE_NAME | sed -r 's/^ *| *$//g')
> # get customer name
> CUST_NAME=$($PSQL "SELECT name FROM customers WHERE customer_id = $CUST_ID")
> CUST_NAME_FORMATTED=$(echo $CUST_NAME | sed -r 's/^ *| *$//g')
> echo -e "\nI have put you down for a $SERVICE_NAME_FORMATTED at $SERVICE_TIME, $CUST_NAME_FORMATTED."
> }
> 
> MENU

Is there some other way to display the list of services each time an erroneous input is received?

Thank you in advance for your help.

I tried a different way, which as far as I can tell directly prints the list of services again rather than sending the user back to the initial menu containing the list:

#! /bin/bash
PSQL="psql -X --username=freecodecamp --dbname=salon --tuples-only -c"

echo -e "\n~~~~~~~~~~Hairdresser's~~~~~~~~~~\n"

MENU()
{
  echo -e "\nWelcome to the hairdresser's. Take a look at our services:\n"
  # get services
  SERVICES=$($PSQL "SELECT service_id, name FROM services ORDER BY service_id")
  # display services
  echo "$SERVICES" | while read SERVICE_ID BAR SERVICE
  do
    echo -e "$SERVICE_ID) "$SERVICE""
  done
  echo -e "\nWhich service would you like today?"
  GET_DETAILS
}

GET_DETAILS()
{
read SERVICE_ID_SELECTED
# get service
SELECTED_SERVICE=$($PSQL "SELECT service_id FROM services WHERE service_id = $SERVICE_ID_SELECTED")
# if service doesn't exist
if [[ -z $SELECTED_SERVICE ]]
then
  echo -e "\nThat is not a valid service. Please select a service from the list.\n"
  # get services
  echo "$SERVICES" | while read SERVICE_ID BAR SERVICE
  do
    echo -e "$SERVICE_ID) "$SERVICE""
  done
  GET_DETAILS
else
  # get phone number
  echo -e "\nWhat is your phone number?"
  read CUSTOMER_PHONE
  # if customer doesn't exist
  EXISTING_CUSTOMER_NAME=$($PSQL "SELECT name FROM customers WHERE phone = '$CUSTOMER_PHONE'")
  if [[ -z $EXISTING_CUSTOMER_NAME ]]
  then
    # get customer name
    echo -e "\nIt seems you have not visited us before. Welcome! What is your name?"
    read CUSTOMER_NAME
    # insert customer
    INSERT_CUSTOMER_RESULT=$($PSQL "INSERT INTO customers(name, phone) VALUES('$CUSTOMER_NAME', '$CUSTOMER_PHONE')")
  else
  EXISTING_CUSTOMER_NAME_FORMATTED=$(echo $EXISTING_CUSTOMER_NAME | sed -r 's/^ *| *$//g')
    echo -e "\nWelcome back, $EXISTING_CUSTOMER_NAME_FORMATTED." 
  fi
fi
MAKE_APPO
}

MAKE_APPO()
{
echo -e "\nWhat time would you like to come in?"
read SERVICE_TIME
# get customer_id
CUST_ID=$($PSQL "SELECT customer_id FROM customers WHERE phone = '$CUSTOMER_PHONE'")
# add appointment
ADD_APPO_RESULT=$($PSQL "INSERT INTO appointments(customer_id, service_id, time) VALUES($CUST_ID, $SELECTED_SERVICE, '$SERVICE_TIME')")
# get service name
SERVICE_NAME=$($PSQL "SELECT name FROM services WHERE service_id = $SELECTED_SERVICE")
SERVICE_NAME_FORMATTED=$(echo $SERVICE_NAME | sed -r 's/^ *| *$//g')
# get customer name
CUST_NAME=$($PSQL "SELECT name FROM customers WHERE customer_id = $CUST_ID")
CUST_NAME_FORMATTED=$(echo $CUST_NAME | sed -r 's/^ *| *$//g')
echo -e "\nI have put you down for a $SERVICE_NAME_FORMATTED at $SERVICE_TIME, $CUST_NAME_FORMATTED."
}

MENU

And that didn’t pass either. I’m not sure what else to try.

I played with another person’s code who was having a similar problem. Here’s the solution I found for them. I didn’t quite figure out why the test wasn’t passing with their code. I would try something like that - let us know if it works. I will take another look at the tests and see if I can see anything wrong with it.

I’m afraid it’s still not working. I changed my code so it looks like this:

MENU()
{
  echo -e "\nWelcome to the hairdresser's. Take a look at our services:\n"
  # get services
  SERVICES=$($PSQL "SELECT service_id, name FROM services ORDER BY service_id")
  # display services
  echo "$SERVICES" | while IFS="|" read SERVICE_ID NAME
  do
    echo -e "$SERVICE_ID) "$NAME""
  done
  echo -e "\nWhich service would you like today?"
  GET_DETAILS
}

GET_DETAILS()
{
read SERVICE_ID_SELECTED
# get service
SELECTED_SERVICE=$($PSQL "SELECT service_id FROM services WHERE service_id = $SERVICE_ID_SELECTED")
# if service doesn't exist
if [[ -z $SELECTED_SERVICE ]]
then
  echo -e "\nThat is not a valid service. Please select a service from the list.\n"
  echo "$SERVICES" | while IFS="|" read SERVICE_ID NAME
  do
    echo -e "$SERVICE_ID) "$NAME""
  done
  GET_DETAILS

My lines for displaying the list of services the first time and when an invalid service is selected looks like this:

echo "$SERVICES" | while IFS="|" read SERVICE_ID NAME
  do
    echo -e "$SERVICE_ID) "$NAME""
  done

When I include the IFS specifier and remove BAR from the read command, it no longer passes the initial test for ‘You should display a numbered list of the services you offer before the first prompt for input’, which seems like a mistake as well because the output looks like this:

image

Removing the IFS specifier produces this output:

image

Which also doesn’t pass that initial test about displaying a list of services. It seems like the BAR has to be there in the read command , which produces this output

image

Which passes the initial test but not the test for when an invalid service is entered. I’m not sure how you got the checks to pass with the code you linked. What would adding a ` to the NAME variable do? When I include that it just produces errors in my script, and the checks still don’t pass.

It’s frustrating that I have to mess around like this when my code does do what the tests specify.

When I include the IFS specifier and remove BAR from the read command, it no longer passes the initial test

Yea, currently the output needs to be pretty strictly formatted I think. The extra spaces before the numbers might be alright, but probably not the ones between the number and parenthesis.

What would adding a ` to the NAME variable do?

That’s just a typo - it shouldn’t be there. I removed it from that post.

Sorry, for your frustration. I will try to run your code to see if I can get it to pass with slight modifications and get back to you. I will see if we can make those tests a little more lenient, as well.

Can you share a dump of your database using the command in the instructions @chriswallacet?

--
-- PostgreSQL database dump
--

-- Dumped from database version 12.9 (Ubuntu 12.9-2.pgdg20.04+1)
-- Dumped by pg_dump version 12.9 (Ubuntu 12.9-2.pgdg20.04+1)

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

DROP DATABASE salon;
--
-- Name: salon; Type: DATABASE; Schema: -; Owner: freecodecamp
--

CREATE DATABASE salon WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'C.UTF-8' LC_CTYPE = 'C.UTF-8';


ALTER DATABASE salon OWNER TO freecodecamp;

\connect salon

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

SET default_tablespace = '';

SET default_table_access_method = heap;

--
-- Name: appointments; Type: TABLE; Schema: public; Owner: freecodecamp
--

CREATE TABLE public.appointments (
    appointment_id integer NOT NULL,
    customer_id integer,
    service_id integer,
    "time" character varying(10)
);


ALTER TABLE public.appointments OWNER TO freecodecamp;

--
-- Name: appointments_appointment_id_seq; Type: SEQUENCE; Schema: public; Owner: freecodecamp
--

CREATE SEQUENCE public.appointments_appointment_id_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;


ALTER TABLE public.appointments_appointment_id_seq OWNER TO freecodecamp;

--
-- Name: appointments_appointment_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: freecodecamp
--

ALTER SEQUENCE public.appointments_appointment_id_seq OWNED BY public.appointments.appointment_id;


--
-- Name: customers; Type: TABLE; Schema: public; Owner: freecodecamp
--

CREATE TABLE public.customers (
    customer_id integer NOT NULL,
    name character varying(40),
    phone character varying(12)
);


ALTER TABLE public.customers OWNER TO freecodecamp;

--
-- Name: customers_customer_id_seq; Type: SEQUENCE; Schema: public; Owner: freecodecamp
--

CREATE SEQUENCE public.customers_customer_id_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;


ALTER TABLE public.customers_customer_id_seq OWNER TO freecodecamp;

--
-- Name: customers_customer_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: freecodecamp
--

ALTER SEQUENCE public.customers_customer_id_seq OWNED BY public.customers.customer_id;


--
-- Name: services; Type: TABLE; Schema: public; Owner: freecodecamp
--

CREATE TABLE public.services (
    service_id integer NOT NULL,
    name character varying(30)
);


ALTER TABLE public.services OWNER TO freecodecamp;

--
-- Name: services_service_id_seq; Type: SEQUENCE; Schema: public; Owner: freecodecamp
--

CREATE SEQUENCE public.services_service_id_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;


ALTER TABLE public.services_service_id_seq OWNER TO freecodecamp;

--
-- Name: services_service_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: freecodecamp
--

ALTER SEQUENCE public.services_service_id_seq OWNED BY public.services.service_id;


--
-- Name: appointments appointment_id; Type: DEFAULT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.appointments ALTER COLUMN appointment_id SET DEFAULT nextval('public.appointments_appointment_id_seq'::regclass);


--
-- Name: customers customer_id; Type: DEFAULT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.customers ALTER COLUMN customer_id SET DEFAULT nextval('public.customers_customer_id_seq'::regclass);


--
-- Name: services service_id; Type: DEFAULT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.services ALTER COLUMN service_id SET DEFAULT nextval('public.services_service_id_seq'::regclass);


--
-- Data for Name: appointments; Type: TABLE DATA; Schema: public; Owner: freecodecamp
--

INSERT INTO public.appointments VALUES (24, 18, 1, '10:30');
INSERT INTO public.appointments VALUES (25, 18, 2, '11am');


--
-- Data for Name: customers; Type: TABLE DATA; Schema: public; Owner: freecodecamp
--

INSERT INTO public.customers VALUES (18, 'Fabio', '555-555-5555');


--
-- Data for Name: services; Type: TABLE DATA; Schema: public; Owner: freecodecamp
--

INSERT INTO public.services VALUES (1, 'Men''s cut');
INSERT INTO public.services VALUES (2, 'Ladies'' cut');
INSERT INTO public.services VALUES (3, 'Colouring');
INSERT INTO public.services VALUES (4, 'High/lowlights');
INSERT INTO public.services VALUES (5, 'Extensions');
INSERT INTO public.services VALUES (6, 'Blow dry');
INSERT INTO public.services VALUES (7, 'Shave');


--
-- Name: appointments_appointment_id_seq; Type: SEQUENCE SET; Schema: public; Owner: freecodecamp
--

SELECT pg_catalog.setval('public.appointments_appointment_id_seq', 60, true);


--
-- Name: customers_customer_id_seq; Type: SEQUENCE SET; Schema: public; Owner: freecodecamp
--

SELECT pg_catalog.setval('public.customers_customer_id_seq', 43, true);


--
-- Name: services_service_id_seq; Type: SEQUENCE SET; Schema: public; Owner: freecodecamp
--

SELECT pg_catalog.setval('public.services_service_id_seq', 7, true);


--
-- Name: appointments appointments_pkey; Type: CONSTRAINT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.appointments
    ADD CONSTRAINT appointments_pkey PRIMARY KEY (appointment_id);


--
-- Name: customers customers_phone_key; Type: CONSTRAINT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.customers
    ADD CONSTRAINT customers_phone_key UNIQUE (phone);


--
-- Name: customers customers_pkey; Type: CONSTRAINT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.customers
    ADD CONSTRAINT customers_pkey PRIMARY KEY (customer_id);


--
-- Name: services services_name_key; Type: CONSTRAINT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.services
    ADD CONSTRAINT services_name_key UNIQUE (name);


--
-- Name: services services_pkey; Type: CONSTRAINT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.services
    ADD CONSTRAINT services_pkey PRIMARY KEY (service_id);


--
-- Name: appointments appointments_customer_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.appointments
    ADD CONSTRAINT appointments_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES public.customers(customer_id);


--
-- Name: appointments appointments_service_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.appointments
    ADD CONSTRAINT appointments_service_id_fkey FOREIGN KEY (service_id) REFERENCES public.services(service_id);


--
-- PostgreSQL database dump complete
--

Here. Thanks for taking the time. Yeah I do think the tests could be more lenient too. Keen to hear about what you find works.