The Line of Least Resistance

From ESE205 Wiki
Revision as of 17:18, 12 December 2016 by Devon.essick (talk | contribs)
Jump to navigation Jump to search

Project Overview

Research has shown that many of the typical methods for queueing customers are incredibly inefficient [1]. Many businesses choose to use reservation systems, for many reasons, such as space limitations in their waiting areas, preparation for large parties, and because the first-come, first-serve process is proven to be inefficient. We aim to create a mobile app that customers of three sample restaurants (and time permitting, other businesses like tourist attractions) can download and input their name, party size, and desired reservation time and receive a time to arrive in order to be attended to. The goal is to minimize delay time/maximize predictability because businesses like restaurants, tourist attractions, etc. are meant to be enjoyable, and being given an accurate wait time contributes towards a pleasant experience.

Team Members

  • Devon Essick
  • Andrew Sweren
  • Kjartan Brownell (TA)

Objectives

  • Create a mobile application (iOS) that mirrors what a potential customer of a business could download to "make a reservation" at a business. The app will be simple with an intuitive user interface for those who might not be tech-savvy, and will only require that the user selects which business they want to make a reservation for from a list of three (a small restaurant, a tourist attraction, and a large restaurant), and input their name, group size, and desired reservation time from pre-determined time slots (e.g. 7pm, 7:30pm, 8pm). On the other side, there will be a server (obtained through Amazon Cloud) where the host can input "current conditions" in the business. Once the user submits their information, this data will be analyzed through an algorithm on when they can next be server, and the information will be sent back to the app and the closest available time to their selection will be displayed. We will code with Swift, Apple's programming language, and create a code that when given the user's inputs, and when taken into account the "current situation" at the businesses, will determine a time that the user should arrive in order to be seated. Each time someone submits information, this reservation will be taken into account for the next time sometime submits a reservation, until we reset the conditions back to original.
  • Create multiple "sample" situations for the reservations to be based off of (e.g. a restaurant open from 5pm to 10pm, with 10 tables of various seating capacities)
  • Time permitting: Create a representation of what the host would "see" based on new reservation information inside the app (e.g. once a 3-person group reserves a table for 8pm, we see how full the restaurant is)
  • Time permitting: add additional features linking the app to other iOS Apps, such as putting the reservation or location in Calendar or Apple Maps

Challenges

  • Learning how to create a mobile app, and learning Swift programming language
  • Coding the system that determines when a customer should arrive
  • Creating an approachable and intuitive mobile app user interface for people with no experience to use
  • Utilizing and coding onto the server
  • Making sure we take into account important inputs about a given business so that the recommendations are realistic (e.g. understanding even if there are 2 two-person slots available at a given time, a group of four will not split up)
  • Taking into account that even if there is a reservation system in place, people are bound to still show up unannounced, and what the impact on the business could be to turn them away
  • Accounting for changes disrupting the way the business operates (e.g. making the business only accessible by reservations could change the type of customers, or making reservations only accessible via mobile app could exclude an older generation)
  • Taking into account that people may make reservations and not show up, which may disrupt the system
  • Making the app reliable (understanding that introducing the app to a business when it does not give accurate times could mean customers do not return)

Budget

  • Device with iOS (provided by team members)- $0
  • Coding software (provided by school) - $0
  • Amazon Cloud server (90 day trial) - $0

Total: $0

Gantt Chart

EssickGantt4.png

Design and Solutions

The app was designed to take five distinct steps, starting and ending with the user interface:

  1. Customers go into the app and choose their restaurant and enter their information (group name, group size, earliest available time and latest available time) and press submit
  2. Code places the reservation info in queue and determines expected time
  3. Server takes in reservation
  4. Code determines if there is an available time within the desired time range
  5. Customers receive their reservation status in the app

User Interface

An example of designing the UI in Xcode. On the left is a View Controller, and on the right is the code that tells the app what happens when the Submit button is pressed
  • The UI for ReserveNow, the app, was created on Xcode, Apple's app development software, using Swift programming language
  • There were View Controllers (i.e. screens on the app) to input reservation info for each restaurant, and for menus of each restaurant
  • Three fictitious restaurants were created (Higgins Restaurant, Killer Burger, and Donna's Dumplings)
  • Most of the interface was created programmatically, and some was created using the "Utilities" bar, which allows you to make changes like font size without writing a line of code
  • The reservation info was put in JSON format to be easily passed onto the algorithm
  • The code called upon Amazon Web Services' Cloud Logic Lambda functions
  • Customers receive a notification for whether their reservation was successful or not, and what time within their time frame it is for

Algorithm

  • Reservation object is created
  • reserve method is called on reservation in Lambda function. This method places it in the respective queue (corresponding to Restaurant and size)
  • Within the reserve method the increase method is called. This compares the reservation to a previous reservation in the queue (number of spaces back is the number of tables of the desired size in the desired restaurant). This updates the expected time
  • If the expected time is within the time frame specified by the user, he or she will receive a message saying that the reservation was successful. Otherwise the reservation will be automatically cancelled and the user will get a message saying the reservation was automatically cancelled
  • Errors were immediately sent back to the UI if the information had been entered incorrectly (e.g. size not an integer value, latest available time entered as earlier than the earliest available time, etc)

The increase method, which was used as a helper method to make sure all the expected times were right in multiple other methods:

        // int i represents the place in the queue, int s represents the size of the reservation
        public void increase(int i, int s) {
		Reservation[] party;
		int n;
                // based on the size of the reservation, the appropriate queue and number of tables is referenced.
		switch(s) {
		case 1: 
			party = this.one;
			n = this.num1;
			break;
		case 2:
			party = this.two;
			n = this.num2;
			break;
		case 3:
			party = this.three;
			n = this.num3;
			break;
		case 4:
			party = this.four;
			n = this.num4;
			break;
		case 5:
			party = this.five;
			n = this.num5;
			break;
		case 6:
			party = this.six;
			n = this.num6;
			break;
		case 7:
			party = this.seven;
			n = this.num7;
			break;
		case 8:
			party = this.eight;
			n = this.num8;
			break;
		case 9:
			party = this.nine;
			n = this.num9;
			break;
		case 10:
			party = this.ten;
			n = this.num10;
			break;
		default: return;
		}
               // if statement representing a case where the reservation represents a party that is currenty seated.
		if (i < n) {
			switch(s) {
			case 1: 
				this.one = party;
				this.num1 = n;
				break;
			case 2:
				this.two = party;
				this.num2 = n;
				break;
			case 3:
				this.three = party;
				this.num3 = n;
				break;
			case 4:
				this.four = party;
				this.num4 = n;
				break;
			case 5:
				this.five = party;
				this.num5 = n;
				break;
			case 6:
				this.six = party;
				this.num6 = n;
				break;
			case 7:
				this.seven = party;
				this.num7 = n;
				break;
			case 8:
				this.eight = party;
				this.num8 = n;
				break;
			case 9:
				this.nine = party;
				this.num9 = n;
				break;
			case 10:
				this.ten = party;
				this.num10 = n;
				break;
			default: return;
			}
			return;
		}
                // if statement representing a case where the party referenced does not exist.
		if (party[i] == null) {
			switch(s) {
			case 1: 
				this.one = party;
				this.num1 = n;
				break;
			case 2:
				this.two = party;
				this.num2 = n;
				break;
			case 3:
				this.three = party;
				this.num3 = n;
				break;
			case 4:
				this.four = party;
				this.num4 = n;
				break;
			case 5:
				this.five = party;
				this.num5 = n;
				break;
			case 6:
				this.six = party;
				this.num6 = n;
				break;
			case 7:
				this.seven = party;
				this.num7 = n;
				break;
			case 8:
				this.eight = party;
				this.num8 = n;
				break;
			case 9:
				this.nine = party;
				this.num9 = n;
				break;
			case 10:
				this.ten = party;
				this.num10 = n;
				break;
			default: return;
			}
			return;
		}
		else {
                        // Time object used to reference the expected time of the reservation "above" (see note below) the referenced one. 
			Time t = new Time(party[i-n].expected.getHours(),party[i-n].expected.getMinutes());
                        // Changes the time to be at least the average time spent in the restaurant later than the expected time of the reservation above it.
			t.changeMinutes(this.avg);
                        // Sets the target reservation to be the later of its desired early time, and the average time spent in the restaurant after the expected time of the reservation above it.
			party[i].changeExpectedTime(t);
                        // if statement if the reservation "below" is null
			if (party[i+n] == null) {
				switch(s) {
				case 1: 
					this.one = party;
					this.num1 = n;
					break;
				case 2:
					this.two = party;
					this.num2 = n;
					break;
				case 3:
					this.three = party;
					this.num3 = n;
					break;
				case 4:
					this.four = party;
					this.num4 = n;
					break;
				case 5:
					this.five = party;
					this.num5 = n;
					break;
				case 6:
					this.six = party;
					this.num6 = n;
					break;
				case 7:
					this.seven = party;
					this.num7 = n;
					break;
				case 8:
					this.eight = party;
					this.num8 = n;
					break;
				case 9:
					this.nine = party;
					this.num9 = n;
					break;
				case 10:
					this.ten = party;
					this.num10 = n;
					break;
				default: return;
				}
				return;
			}
			else {
                                // if there is a reservation below the one targeted, the increase method is called on it.
				increase(i+n,s);
			}
		}
	}

Note: each queue is represented by a Reservation array. While one dimensional, they are treated as two dimensional, with each row having a length of the number of tables in the specified restaurant at the specified size.

Server

Algorithm used to manage reservations was written in Java and includes methods that allow customers to get a table as early as possible and assures that tables are filled as often as possible • Two custom objects (Reservation and Restaurant) are included to represent each restaurant and reservations in its system • Each reservation object has “name”, three “times” (early, late, and expected), “size”, and “restaurant". • Each restaurant object has opening and closing time, name, and ten of each of the following: arrays of reservations, integers to represent number of tables and number of reservations in a queue • Each restaurant has ten queues corresponding to different reservation sizes which are represented by an array of reservation objects of length 1000

Results and Analysis

User Interface

All of the View Controllers for of the three fictional restaurants, Killer Burger.

The UI ended up where we wanted it to be, but due to other issues, we didn't have time to add extra features to it. For example, at the beginning of the semester we wanted to add a feature where restaurants could log in through a User Identity feature and see a more attractive interface of current reservations, rather than having to see them through the Amazon Web Services server. We also wanted to do the other "time permitting" objective of linking the app to other iOS Apps. But these proved to be too complicated to implement. A huge issue we faced was the fact that AWS changed their whole protocol for calling functions from Xcode in the middle of the semester. We had figured out how to call them before the second Project Evaluation, but almost right after, they changed it to a much more sophisticated process that was a lot harder to interpret and adapt to our code. Luckily, we figured out a way to trick the system into using an old Lambda function instead of the new APIs, but it took up a lot of valuable time we could have been using to improve the features of the app.

Algorithm

The algorithm, in and of itself, worked to its full purpose. We were able to get the algorithm to accurately calculate expected times based on when people had previously made reservations. We were also able to get it to constantly update the times each time someone was seated and do so in an accurate manner. Additionally, the algorithm was able to send all the necessary information to the server.

Server

While we were able to successfully integrate the app with the server, we were only able to have it perform one function, which was the initial attempt to reserve the party. Once the party was reserved and approved, we were not able to modify afterwards. In other words, only the customer could use the app for its intended purpose, not the restaurant.

Overall

We had a lot of trouble settling on exactly what we wanted to achieve with the project, and didn't fully understand what we were going to do until after the first Project Evaluation. Even then, we were going into completely uncharted territory because neither of us or Kjartan had experience with building an app, and so we weren't sure actually how much we could expect to achieve in a relatively short amount of time. Luckily, we finished what we set out to do just in time, as we didn't get the algorithm completely integrated with the server until the weekend before the Demo.

Although we wish we achieved more, and got to add features mentioned in our proposal, we integrated three separate components and created a working app, and met our main objectives.

While we did have a working algorithm and were able to integrate the app with the server, we were not able to have the application perform all of its features. All we were able to do was have a person make the reservation and see that it was successful, essentially allowing a customer to send information to the restaurant, but the restaurant cannot do anything other than accept the reservation. There are a few reasons for this failure. One of them is due to the limitations of the Amazon databases. Because the algorithm used custom java objects, the amazon server was not able to recognize them unless they were broken up into parts. This made it extremely difficult to keep track of every queue that the reservation in.