Cinema ticket booking using BASH

Cinema ticket booking using BASH

This assignment requires you to write a portion of the self-service ticketing kiosk for a cinema using the bourne-again shell (bash).    The self-service ticketing system will allow the public to check the availability of the cinema tickets for a particular movie and choose their own seating in the theatre as well as to purchase tickets themselves.    A suggested interactive ticketing menu with color can be as follows:

Main Menu

JACKY Theatre’s Self-service Ticketing

  • List all Movies and Show times
  • Fast booking (where system will automatically select best seat)
  • To select theatre’s seat manually
  • Search by Screening times or by Movie title
  • Quit

For a color menu, one can use the following template for writing colored text on a colored background.

echo -e ‘\E[COLOR1;COLOR2mSome text goes here.’

Choice 1 of the main menu will provide a list of all the movies and show times the theatre are screening.  The list of movies can be populated from a flat file.  Below is a sample of the file format with comma as the delimiter.  You can add in extra fields if required.

[Showtimes], [Movie Title], [Vacancy]
1300 – 2Oct, UnderCovers, Yes
1600 – 2Oct, RoboCop, No
1700 – 2Oct, Predators, Yes
 
 

While generating this list of movies for display, you are to include if the movies are sold out or still available by checking on the flat in the file.  You are to use stream editor (sed) command to assist in the report generation by checking the vacancy column with the substitution of  “Yes” with “SOLD OUT” for the respective movies and “No” with “Ticket available”.  Simultaneously you are to use sed to swap the column of the Movie Title and Showtimes as you r program read from the file.  Sample output can be as follows:

JACKY Theatre’s Screening Movies
Movie Title     Showtimes                                         Vacancy

UnderCovers   1300-2Oct                               Ticket available

RoboCop                      1600-2Oct                               SOLD OUT

Predators                    1700-2Oct                               Ticket available

…                                 …

Choice 2 is a quick way of ticket purchase where the system has some intelligence in generating the next optimum available seat for customer to make a quick purchase.  You can assume that the seats which are nearer to the screen and more centralized are the better ones.

Choice 3 will display the seats that are available as well as not, in a matrix or pattern as shown below.  You can use a while loop to implement this.

To select theatre’s seat manually

_______SCREEN________

  A B C D E
1 X        
2   X X    
3         X
4   X X X X

Enter the seat number(s) you want (eg: B3 or B1,C1,D1) :

C3,D3

To select theatre’s seat manually

_______SCREEN________

  A B C D E
1 X        
2   X X    
3     X X X
4   X X X X

Total ticket(s) price for 2 tickets is $10

To confirm your seats in Marked in Blue, press Y or N:

Y

For both fast and manual booking, the ticketing system can also compute the total price chargeable as shown above.

Choice 4 will allow customer to search by show times or by movie title.  For instance, the customer might like to find out what movies are there screening at 19:00.   You can use commands like egrep or grep coupled with regular expressions such as ^, $, [] etc. to search through the records.

You will need to create a file system so that the system will know the seat vacancies for the different movies at different show times. Some entries validation is required to check if the seat number entered is valid or available for sales.

In your shell program, you can use commands such as echo, grep, awk, cut, >>, read, expr, sort etc. to store, locate, display, remove and sort.   If else control structure, case structure, while and for loop can be incorporated as well.

Execution of your program would be as follows:

$bash ticketing.sh      or   $ticketing.sh 

labHint2.sh 

#display main ticketing menu

display_menu()

{

# Called by run_menu

echo

echo “– Theatre’s Self-service Ticketing –”

echo -n “1. ”

echo -e ‘\E[1;32;40mList all Movies and Show time\E[0m’

echo -n “2. ”

echo -e ‘\E[1;32;40mDisplay theatre’s seat \E[0m’

echo -n “q. ”

echo -e ‘\E[1;31;47mQuit\E[0m’

echo -en “Enter your selection: ”

}

# List out available movies

list_movies()

{

# Called by run_menu

old_IFS=$IFS

IFS=$’\n’

print_movie_header

for LINE in `sed -e ‘s/Yes/Ticket Available/g’ -e ‘s/No/SOLD OUT/g’ movielist.txt`

do

print_movie $LINE

done

IFS=$old_IFS

}

# Output header for movie listing

# Catered for both numbered and non-numbered list

print_movie_header()

{

echo -e ‘\E[1;32;40m’

if [ $# == “1” ];then

echo -n ”   ”

fi

echo -n -e ‘Movie Title’

set_colwidth ‘Movie Title’ 25

echo -n -e ‘Show Time\t’

if [ $# == “1” ];then

echo -n -e “\t”

fi

echo -n ‘Vacancy’

echo -e ‘\E[0m’

}

# Set the width of column

# $1 is the text in the column

# and $2 is the intended column width

set_colwidth()

{

STRING=$1

LENGTH=${#STRING}

for (( i=$LENGTH; i<=$2; i++))

do

echo -n ” ”

done

}

# Output movie entry

print_movie()

{

TIME=`echo $1 | cut -f1 -d “,”`

TITLE=`echo $1 | cut -f2 -d “,”`

AVAILABLE=`echo $1 | cut -f3 -d “,”`

echo -n -e $TITLE

set_colwidth $TITLE 25

echo -n -e $TIME ‘\t’

echo $AVAILABLE

}

# Hint2

# Get current seating arrangement of

# selected movie from seating.txt

movie_data()

{

COUNT=1

old_IFS=$IFS

IFS=$’\n’

for LINE in `cat seating.txt`

do

if test $1 -eq $COUNT

then

display_seats $LINE $2

fi

THEATER[$COUNT]=$LINE

let COUNT=COUNT+1

done

IFS=$old_IFS

}

# Mark occupied seat with a X and

# seats selected by user with a red X

mark_seat()

{

# Called by display_seats

 

if [ $(echo “$1” | grep -c “$2$3”) -gt 0 ]

then

echo -n “X”

set_colwidth “” 5

elif [ $(echo “$4” | grep -c “$2$3”) -gt 0 ]

then

echo -en ‘\E[1;31mX\E[0m’

set_colwidth “” 5

else

set_colwidth “” 6

fi

}

# Print out theater’s seating arrangement

display_seats()

{

COL=5

ROW=4

echo

echo “—————————————”

echo -e ‘\E[1;34;47m—————-SCREEN—————–\E[0m’

echo “—————————————”

for (( x=0; x<=$ROW; x++))

do

echo -n “$x” | tr “0” ” ”

for (( j=0; j<=$COL; j++))

do

if [ $x == “0” ]

then

echo -n $j | tr “012345” ” ABCDE”

set_colwidth “” 5

else

CURR_COL=$(echo $j | tr “12345” “ABCDE”)

if [ $j == “0” ]

then

set_colwidth “” 6

else

mark_seat $1 $CURR_COL $x $2

fi

fi

done

echo “”

done

echo “—————————————”

}

# Select and book seat manually

select_seat()

{

# Called by run_menu

COUNT=0

echo

echo “– Select A Seat Manually –”

echo

old_IFS=$IFS

IFS=$’\n’

print_movie_header “numbered”

for LINE in `sed -e ‘s/Yes/Ticket Available/g’ -e ‘s/No/SOLD OUT/g’ movielist.txt `;do

let COUNT=COUNT+1

echo -n “$COUNT. ”

print_movie $LINE

done

IFS=$old_IFS

echo

# Select movie to book

echo -en “Select Movie To Book (Enter 1 to ${COUNT}): ”

read NUM

NUMERIC=0

while [ “$NUMERIC” != “1” ];do

for (( x=$COUNT; x>=1; x–))

do

if [ $NUM == “$x” ];then

NUMERIC=1

fi

done

if [ “$NUMERIC” != “1” ];then

echo -en “Invalid Movie Selected, Try Again (Enter 1 to ${COUNT}): ”

read NUM

fi

done

movie_data $NUM

echo

old_IFS=$IFS

IFS=$’\n’

echo

}

# Main menu navigation

run_menu()

{

i=-1

while [ “$i” != “q” ]; do

display_menu

read i

i=`echo $i | tr ‘[A-Z]’ ‘[a-z]’`

case “$i” in

“1”)

list_movies

;;

“2”)

select_seat

;;

“q”)

echo “GoodBye, Have A Nice Day”

exit 0

;;

*)

echo “Unrecognised Input.”

;;

esac

done

}

#———————————————-#

# ———PROGRAM SCRIPT START HERE———- #

#———————————————-#

if [ ! -f movielist.txt ]; then

echo “Error: Movie list is not available”

fi

run_menu 

Solution

declare -a THEATER

#display main ticketing menu

display_menu()

{

# Called by run_menu

echo

echo -e ”   \E[1;37;100m      — Theatre’s Self-service Ticketing —      \E[0m”

echo

echo -n “1. ”

echo -e ‘\E[1;32;40mList all Movies and Show time                     \E[0m’

echo -n “2. ”

echo -e ‘\E[1;32;40mFast booking                                      \E[0m’

echo -n “3. ”

echo -e ‘\E[1;32;40mSelect theatre’s seat manually                    \E[0m’

echo -n “4. ”

echo -e ‘\E[1;32;40mSearch by Screening times or by Movie title       \E[0m’

echo -n “q. ”

echo -e ‘\E[1;31;47mQuit                                              \E[0m’

echo -en “Enter your selection: ”

}

# List out available movies

list_movies()

{

# Called by run_menu

echo

echo “– Theatre’s Screening Movies  –”

echo

old_IFS=$IFS

IFS=$’\n’

print_movie_header

for LINE in `sed -e ‘s/Yes/Ticket Available/g’ -e ‘s/No/SOLD OUT/g’ movielist.txt`

do

print_movie $LINE

done

IFS=$old_IFS

}

filter_movies()

{

# Called by run_menu

echo

echo “– Search Theatre’s Screening Movies  –”

echo

echo -e “1. Search by show times”

echo -e “2. Search by movie title”

echo -en “Select search option (Enter 1 or 2): ”

read opt

if [ “$opt” == “1” ]; then

pattern_beg=’^’

pattern_end=’,’

echo -en “Enter the show time: ”

else

pattern_beg=’,’

pattern_end=’,’

echo -en “Enter movie title: ”

fi

read search

pattern=$pattern_beg$search$pattern_end

old_IFS=$IFS

IFS=$’\n’

print_movie_header

for LINE in `sed -e ‘s/Yes/Ticket Available/g’ -e ‘s/No/SOLD OUT/g’ movielist.txt | grep $pattern`

do

print_movie $LINE

done

IFS=$old_IFS

}

# Output header for movie listing

# Catered for both numbered and non-numbered list

print_movie_header()

{

echo -e ‘\E[1;32;40m’

if [ $# == “1” ];then

echo -n ”   ”

fi

echo -n -e ‘Movie Title’

set_colwidth ‘Movie Title’ 25

echo -n -e ‘Show Time\t’

if [ $# == “1” ];then

echo -n -e “\t”

fi

echo -n ‘Vacancy’

echo -e ‘\E[0m’

}

# Set the width of column

# $1 is the text in the column

# and $2 is the intended column width

set_colwidth()

{

STRING=$1

LENGTH=${#STRING}

for (( i=$LENGTH; i<=$2; i++))

do

echo -n ” ”

done

}

# Output movie entry

print_movie()

{

TIME=`echo $1 | cut -f1 -d “,”`

TITLE=`echo $1 | cut -f2 -d “,”`

AVAILABLE=`echo $1 | cut -f3 -d “,”`

echo -n -e $TITLE

set_colwidth $TITLE 25

echo -n -e $TIME ‘\t’

echo $AVAILABLE

}

read_movie_data()

{

COUNT=1

old_IFS=$IFS

IFS=$’\n’

for LINE in `cat seating.txt`; do

THEATER[$COUNT]=$LINE

let COUNT=COUNT+1

done

IFS=$old_IFS

}

# Hint2

# Get current seating arrangement of

# selected movie from seating.txt

movie_data()

{

COUNT=1

LINE=${THEATER[$1]}

display_seats $LINE $2

}

# Mark occupied seat with a X and

# seats selected by user with a red X

mark_seat()

{

# Called by display_seats

 

if [ $(echo “$1” | grep -c “$2$3”) -gt 0 ]

then

echo -n “X”

set_colwidth “” 5

elif [ $(echo “$4” | grep -c “$2$3”) -gt 0 ]

then

echo -en ‘\E[1;31mX\E[0m’

set_colwidth “” 5

else

set_colwidth “” 6

fi

}

# Print out theater’s seating arrangement

display_seats()

{

COL=5

ROW=4

echo

echo “—————————————”

echo -e ‘\E[1;34;47m—————-SCREEN—————–\E[0m’

echo “—————————————”

for (( x=0; x<=$ROW; x++))

do

echo -n “$x” | tr “0” ” ”

for (( j=0; j<=$COL; j++))

do

if [ $x == “0” ]

then

echo -n $j | tr “012345” ” ABCDE”

set_colwidth “” 5

else

CURR_COL=$(echo $j | tr “12345” “ABCDE”)

if [ $j == “0” ]

then

set_colwidth “” 6

else

mark_seat $1 $CURR_COL $x $2

fi

fi

done

echo “”

done

echo “—————————————”

}

# Select and book seat manually

select_seat()

{

# Called by run_menu

COUNT=0

echo

echo “– Select A Seat Manually –”

echo

old_IFS=$IFS

IFS=$’\n’

print_movie_header “numbered”

for LINE in `sed -e ‘s/Yes/Ticket Available/g’ -e ‘s/No/SOLD OUT/g’ movielist.txt `;do

let COUNT=COUNT+1

echo -n “$COUNT. ”

print_movie $LINE

done

IFS=$old_IFS

echo

# Select movie to book

echo -en “Select Movie To Book (Enter 1 to ${COUNT}): ”

read NUM

NUMERIC=0

while [ “$NUMERIC” != “1” ];do

for (( x=$COUNT; x>=1; x–))

do

if [ $NUM == “$x” ];then

NUMERIC=1

fi

done

if [ “$NUMERIC” != “1” ];then

echo -en “Invalid Movie Selected, Try Again (Enter 1 to ${COUNT}): ”

read NUM

fi

done

movie_data $NUM

echo

all_valid=0

while [ $all_valid != “1” ]; do

echo -en “Enter the seat number(s) you want (eg: B3 or B1,C1,D1): ”

read selection

all_valid=1

for seat in `echo $selection | tr ‘,’ ‘\n’`; do

if [[ ! (“${#seat}” == “2” && “ABCDE” =~ “${seat:0:1}” && “12345” =~ “${seat:1:2}”) ]]; then

all_valid=0

fi

done

done

movie_data $NUM $selection

echo

num_tickets=$(echo $selection | tr ‘,’ ‘\n’ | wc -l)

price=$((num_tickets * 10))

echo -e “Total ticket(s) price for $num_tickets tickets is \$$price”

echo -e “To confirm your seats Marked in Red, press Y or N:”

read confirm

if [[ “$confirm” == “Y” || “$confirm” == “y” ]]; then

THEATER[$NUM]=${THEATER[$NUM]}”,”$selection

fi

old_IFS=$IFS

IFS=$’\n’

IFS=$old_IFS

echo

}

# Main menu navigation

run_menu()

{

i=-1

while [ “$i” != “q” ]; do

display_menu

read i

i=`echo $i | tr ‘[A-Z]’ ‘[a-z]’`

case “$i” in

“1”)

list_movies

;;

“2”)

select_seat

;;

“3”)

select_seat

;;

“4”)

filter_movies

;;

“q”)

echo “GoodBye, Have A Nice Day”

exit 0

;;

*)

echo “Unrecognised Input.”

;;

esac

done

}

#———————————————-#

# ———PROGRAM SCRIPT START HERE———- #

#———————————————-#

if [ ! -f movielist.txt ]; then

echo “Error: Movie list is not available”

fi

read_movie_data

run_menu