Number guessing game test failed

I refactored my code again and again. Now I only use ONE table to store user_id, name, game_counter, best_guess. Still I can’t pass the “Enter your username:” test.
Thanks for help!

code:

#!/bin/bash

SECRET=$(($RANDOM % 1000 + 1))

PSQL="psql --username=freecodecamp --dbname=number_guess -t --no-align -c"

check_username(){
  USERNAME=$1
  LENGTH=$(expr length "$USERNAME")
  if [[ ! -z $USERNAME ]]
  then
    if [[ $LENGTH -le 22 ]]
    then
      echo $USERNAME
    else
      echo ""
      exit
    fi
  else
    echo ""
    exit
  fi
}

is_integer(){
  if [[ $1 =~ ^[0-9]+$ ]]
  then
    echo true
  else
    echo false
  fi
}

guess(){
  echo "Guess the secret number between 1 and 1000:"
  while [[ $GUESS -ne $SECRET ]]
  do
    read GUESS
    if [[ $(is_integer $GUESS) = 'false' ]]
    then
      echo "That is not an integer, guess again:"
    elif [[ $(is_integer $GUESS) = 'true' ]]
    then
      if [[ $GUESS -lt $SECRET ]]
      then
        ((GUESSES++))
        echo "It's higher than that, guess again:"
      elif [[ $GUESS -gt $SECRET ]]
      then
        ((GUESSES++))
        echo "It's lower than that, guess again:"
      elif [[ $GUESS -eq $SECRET ]]
      then
        ((GUESSES++))
        echo "You guessed it in $GUESSES tries. The secret number was $SECRET. Nice job!"
      fi
    fi
  done
}

is_newuser(){
  USER_QUERY=$($PSQL "select user_id from users where name = '$1'")
  if [[ -z $USER_QUERY ]]
  then
    IS_NEWUSER=true
  else
    IS_NEWUSER=false
  fi
  echo $IS_NEWUSER
}

get_user_id(){
  if [[ $(is_newuser $1) = 'true' ]]
  then
    USER_INSERT=$($PSQL "insert into users(name) values('$1')")
    if [[ ! $USER_INSERT = "INSERT 0 1" ]]
    then
      echo -e "Failed to add new user."
      exit
    fi
  fi
  USER_ID=$($PSQL "select user_id from users where name = '$1'")
  if [[ -z $USER_ID ]]
  then
    echo "Failed to get user id."
    exit
  else
    echo $USER_ID
  fi
}

get_game_counter(){
  GAME_COUNTER=$($PSQL "select game_counter from users where user_id = $1")
  echo $GAME_COUNTER
}

update_game_counter(){
  UPDATE_GAME_COUNTER=$($PSQL "update users set game_counter = $2 where user_id = $1")
  if [[ $UPDATE_GAME_COUNTER = 'UPDATE 1' ]]
  then
    echo 0
  else
    echo 1
  fi
}

get_best_guess(){
  BEST_GUESS=$($PSQL "select best_guess from users where user_id = $1")
  echo $BEST_GUESS
}

update_best_guess(){
  UPDATE_BEST_GUESS=$($PSQL "update users set best_guess = $2 where user_id = $1")
  if [[ $UPDATE_BEST_GUESS = 'UPDATE 1' ]]
  then
    echo 0
  else
    echo 1
  fi
}

main(){
  GUESSES=0
  echo "Enter you username:"
  read USERNAME
  VALID_NAME=$(check_username $USERNAME)
  if [[ -z $VALID_NAME ]]
  then
    echo "Please input user name. User name should have no more than 22 characters."
    exit
  fi
  IS_NEWUSER=$(is_newuser $VALID_NAME)
  USER_ID=$(get_user_id $VALID_NAME)
  GAME_COUNTER=$(get_game_counter $USER_ID)
  BEST_GUESS=$(get_best_guess $USER_ID)
  if [ $IS_NEWUSER = 'true' ]
  then
    echo "Welcome, $VALID_NAME! It looks like this is your first time here."
  elif [ $IS_NEWUSER = 'false' ]
  then
    echo "Welcome back, $VALID_NAME! You have played $GAME_COUNTER games, and your best game took $BEST_GUESS guesses."
  fi
  guess
  if [[ $GUESSES -gt 0 ]]
  then
    ((GAME_COUNTER++))
    UPDATE_COUNTER_RESULT=$(update_game_counter $USER_ID $GAME_COUNTER)
  fi
  if [[ $BEST_GUESS -eq 0 ]]
  then
    UPDATA_BEST_RESULT=$(update_best_guess $USER_ID $GUESSES)
  elif [[ $BEST_GUESS -gt 0 ]]
  then
    if [[ $GUESSES -lt $BEST_GUESS ]]
    then
      UPDATA_BEST_RESULT=$(update_best_guess $USER_ID $GUESSES)
    fi
  fi
}

#echo $SECRET
main

Could you share the dump of your database as well?

Here is a dump of database.

--
-- 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 number_guess;
--
-- Name: number_guess; Type: DATABASE; Schema: -; Owner: freecodecamp
--

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


ALTER DATABASE number_guess OWNER TO freecodecamp;

\connect number_guess

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: users; Type: TABLE; Schema: public; Owner: freecodecamp
--

CREATE TABLE public.users (
    user_id integer NOT NULL,
    name character varying(22) NOT NULL,
    game_counter integer DEFAULT 0,
    best_guess integer DEFAULT 0
);


ALTER TABLE public.users OWNER TO freecodecamp;

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

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


ALTER TABLE public.users_user_id_seq OWNER TO freecodecamp;

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

ALTER SEQUENCE public.users_user_id_seq OWNED BY public.users.user_id;


--
-- Name: users user_id; Type: DEFAULT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.users ALTER COLUMN user_id SET DEFAULT nextval('public.users_user_id_seq'::regclass);


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

INSERT INTO public.users VALUES (145, 'Tom', 1, 10);
INSERT INTO public.users VALUES (147, 'user_1679512764223', 1, 135);
INSERT INTO public.users VALUES (146, 'user_1679512764224', 2, 47);


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

SELECT pg_catalog.setval('public.users_user_id_seq', 147, true);


--
-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.users
    ADD CONSTRAINT users_pkey PRIMARY KEY (user_id);


--
-- PostgreSQL database dump complete
--

There’s small typo in the message printed for username input: Enter your username:

still can’t pass the test after fix the typo.

How could I check the test log? It should be helpful to figure out what happened.

That’s strange, from what I remember I didn’t change anything else in the script. Test is checking just for that line. Perhaps something further in the script sometimes makes test timeout, as it needs to play complete game.

I’d assume this is correct and move to further tests for now.

I will delete the playground and try it again. Thank you.

I refactored my code to minimize database query times. Now it only query 2 times: read user_id when the game starts and update game_counter and best_guess when the game ends.
The sad part is, the code still can’t pass “Enter your username:” test.

bash code:

#!/bin/bash

SECRET=$(($RANDOM % 1000 + 1))
PSQL="psql --username=freecodecamp --dbname=number_guess -t --no-align -c"

check_username(){
  NAME=$1
  LENGTH=$(expr length "$NAME")
  if [[ ! -z $NAME ]]
  then
    if [[ $LENGTH -le 22 ]]
    then
      echo $NAME
    else
      echo ""
      exit
    fi
  else
    echo ""
    exit
  fi
}

is_integer(){
  if [[ $1 =~ ^[0-9]+$ ]]
  then
    echo true
  else
    echo false
  fi
}

guess(){
  echo "Guess the secret number between 1 and 1000:"
  while [[ $GUESS -ne $SECRET ]]
  do
    read GUESS
    if [[ $(is_integer $GUESS) = 'false' ]]
    then
      echo "That is not an integer, guess again:"
    elif [[ $(is_integer $GUESS) = 'true' ]]
    then
      if [[ $GUESS -lt $SECRET ]]
      then
        ((GUESSES++))
        echo "It's higher than that, guess again:"
      elif [[ $GUESS -gt $SECRET ]]
      then
        ((GUESSES++))
        echo "It's lower than that, guess again:"
      elif [[ $GUESS -eq $SECRET ]]
      then
        ((GUESSES++))
        echo "You guessed it in $GUESSES tries. The secret number was $SECRET. Nice job!"
      fi
    fi
  done
}

get_user_info(){
  USER_QUERY=$($PSQL "select user_id, name, game_counter, best_guess from users where name = '$1'")
  echo $USER_QUERY
}

insert_user_info(){
  USER_INSERT=$($PSQL "insert into users(name, game_counter, best_guess) values('$1', $2, $3)")
}

update_user_info(){
  USER_UPDATE=$($PSQL "update users set game_counter = game_counter + 1, best_guess = $2 where user_id = $1")
}

update_user_info_except_best_guess(){
  USER_UPDATE=$($PSQL "update users set game_counter = game_counter + 1 where user_id = $1")
}

main(){
  echo "Enter your username:"
  read USERNAME
  VALID_NAME=$(check_username $USERNAME)
  if [[ -z $VALID_NAME ]]
  then
    echo "Please input user name. User name should have no more than 22 characters."
    exit
  fi

  USER_INFO=$(get_user_info $VALID_NAME)
  USER_ID=$(echo $USER_INFO | cut -d '|' -f 1)
  USER_NAME=$(echo $USER_INFO | cut -d '|' -f 2)
  GAME_COUNTER=$(echo $USER_INFO | cut -d '|' -f 3)
  BEST_GUESS=$(echo $USER_INFO | cut -d '|' -f 4)
  #echo -e "\n1 $USER_INFO\n2 $USER_ID \n3$USER_NAME \n4$GAME_COUNTER \n5$BEST_GUESS"

  if [[ -z $USER_ID ]]
  then
    echo "Welcome, $VALID_NAME! It looks like this is your first time here."
  else
    echo "Welcome back, $USER_NAME! You have played $GAME_COUNTER games, and your best game took $BEST_GUESS guesses."
  fi

  GUESSES=0
  guess

  if [[ -z $USER_ID ]]
  then
    insert_user_info $VALID_NAME 1 $GUESSES
  else
    if [[ $GUESSES -lt $BEST_GUESS ]]
    then
      update_user_info $USER_ID $GUESSES
    else
      update_user_info_except_best_guess $USER_ID
    fi
  fi
}

#echo $SECRET
main

database dump:

--
-- 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 number_guess;
--
-- Name: number_guess; Type: DATABASE; Schema: -; Owner: freecodecamp
--

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


ALTER DATABASE number_guess OWNER TO freecodecamp;

\connect number_guess

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: users; Type: TABLE; Schema: public; Owner: freecodecamp
--

CREATE TABLE public.users (
    user_id integer NOT NULL,
    name character varying(22) NOT NULL,
    game_counter integer DEFAULT 0,
    best_guess integer DEFAULT 0
);


ALTER TABLE public.users OWNER TO freecodecamp;

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

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


ALTER TABLE public.users_user_id_seq OWNER TO freecodecamp;

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

ALTER SEQUENCE public.users_user_id_seq OWNED BY public.users.user_id;


--
-- Name: users user_id; Type: DEFAULT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.users ALTER COLUMN user_id SET DEFAULT nextval('public.users_user_id_seq'::regclass);


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

INSERT INTO public.users VALUES (24, 'user_1679603473692', 2, 32);
INSERT INTO public.users VALUES (23, 'user_1679603473693', 4, 26);


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

SELECT pg_catalog.setval('public.users_user_id_seq', 24, true);


--
-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: freecodecamp
--

ALTER TABLE ONLY public.users
    ADD CONSTRAINT users_pkey PRIMARY KEY (user_id);


--
-- PostgreSQL database dump complete
--

The test result changes even I don’t touch the code. It’s weird.

I removed all functions and used unreasonable magic to pass the test.
I clicked test 5 or 7times. It passed the test.
There shouldn’t be magic in code. Sad.

Bash code:

#!/bin/bash

SECRET=$(($RANDOM % 1000 + 1))
PSQL="psql --username=freecodecamp --dbname=number_guess -t --no-align -c"

echo "Enter your username:";
read USERNAME

USER_INFO=$($PSQL "select user_id, name, game_counter, best_guess from users where name = '$USERNAME'")
USER_ID=$(echo $USER_INFO | cut -d '|' -f 1)
USER_NAME=$(echo $USER_INFO | cut -d '|' -f 2)
GAME_COUNTER=$(echo $USER_INFO | cut -d '|' -f 3)
BEST_GUESS=$(echo $USER_INFO | cut -d '|' -f 4)

if [[ -z $USER_ID ]]; then
    echo "Welcome, $USERNAME! It looks like this is your first time here.";
else
    echo "Welcome back, $USER_NAME! You have played $GAME_COUNTER games, and your best game took $BEST_GUESS guesses.";
fi

echo "Guess the secret number between 1 and 1000:";
GUESSES=0
GUESS=-1
while [[ $GUESS -ne $SECRET ]]; do
    read GUESS
    if [[ ! $GUESS =~ ^[0-9]+$ ]]; then
        echo "That is not an integer, guess again:";
    elif [[ $GUESS -lt $SECRET ]]; then
        ((GUESSES++))
        echo "It's higher than that, guess again:";
    elif [[ $GUESS -gt $SECRET ]]; then
        ((GUESSES++))
        echo "It's lower than that, guess again:";
    elif [[ $GUESS -eq $SECRET ]]; then
        ((GUESSES++))
        echo "You guessed it in $GUESSES tries. The secret number was $SECRET. Nice job!";
    fi
done

if [[ -z $USER_ID ]]; then
    USER_INSERT=$($PSQL "insert into users(name, game_counter, best_guess) values('$USERNAME', 1, $GUESSES)")
else
    if [[ $GUESSES -lt $BEST_GUESS ]]; then
        USER_UPDATE=$($PSQL "update users set game_counter = game_counter + 1, best_guess = $GUESSES where user_id = $USER_ID")
    else
        USER_UPDATE=$($PSQL "update users set game_counter = game_counter + 1 where user_id = $USER_ID")
    fi
fi