Command Line Coffee command-line interface (CLI) application, made with Python. It’s a back-end project, hosted by a front-end mock terminal made by Code Institute, and deployed using Heroku. It uses Google Sheets for a database, via the gspread API.
It is built to be used by a coffee stall in the foyer of a large co-working space. Customers can make an order from their desks, and then walk down and pick it up when it’s ready. The retro look of a command-line interface gives the user the feeling of using a quirky computer program from the 1970s.
Displays the program title, using pyfiglet for the ASCII art font and termcolor for the text colours.
The time.sleep()
function is used to stagger the printing of the title, and the introduction text is styled with a typing effect.
The user is asked if they want to see the menu.
The coffee menu is pulled from Google Sheets and displayed as a table using tabulate.
The Google Sheet is easily edited by the barista, enabling them to change prices and coffee types without having to edit the Python code.
The ‘coffee-menu’ spreadsheet looks like this inside Google Sheets:
The user is asked to choose the coffee type and the quantity.
The option is given to add to the order.
The user is asked for their name, to be used as an order reference.
Upon entering a name, the order is sent to the Google Sheet ‘orders’, and appears like this to the barista:
The order is then imported back into the program from the ‘orders’ Google Sheet, and displayed to the user as a table, using tabulate.
Underneath the table, Python functions calculate the total cost, waiting time, and display the time of order.
The user is given the option to exit the program, and a ‘thank you’ message is displayed.
All user inputs are validated:
“Shall I show you the menu?”
“Choose an option # (1-6)”
“How many of these would you like?(1-10)”
“Would you like to add more to the order?”
“What name should we write on your order?”
“Press ENTER to exit”
Bug | Fix |
---|---|
There was a bug with the display_pending_order() function, which would retrieve the penultimate order rather than the order that was just made. |
This was because pending_orders = ORDERS_SPREADSHEET.get_all_values() was being defined at the top of the program as a global variable. Moving the variable definition to inside the display_pending_order() function delayed the fetching of the order data until after the order had been made. |
- The coffee menu is currently hard-coded to 6 items. In the future the length of the menu could be pulled from Google Sheets so the stall owner could update the number of items without having to change the code.
- The ability to choose other milk options.
- The ability to take into account all active orders when working out the pickup time with the
calculate_pickup_time()
function.
The Python code was tested with Code Institute’s Python Linter. No errors were found:
Feature | Action | Expected Behaviour | Pass/fail |
---|---|---|---|
Title | Run program | Title & introduction displayed. “Shall I show you the menu?” displayed | PASS |
Display menu dialogue | Enter “y” or “Y” | Displays menu | PASS |
Display menu dialogue | Enter “n” or “N” | Displays title & prints “See ya next time..” | PASS |
Display menu dialogue | Enter anything other than “y”, “Y”, “n” or “N” | Prints “Sorry, this question only accepts 'y' or 'n’. (lower case or capital)” | PASS |
Choose an option (# 1-6) | Enter 1-6 | Prints “Thanks you chose {coffee type}” and asks for quantity required. Adds selection to order_list | PASS |
Choose an option (# 1-6) | Enter a number less than 1, or greater than 6 | Prints "Whoops, the number must be between 1-6” | PASS |
Choose an option (# 1-6) | Enter something other than an integer | Prints "Sorry, that's not a digit” | PASS |
“How many of these would you like?” dialogue | Enter a non-integer | Prints "Sorry, that's not a digit” | PASS |
“How many of these would you like?” dialogue | Enter a number less than 1, or greater than 10 | Prints "Whoops, the number must be between 1-10” | PASS |
“How many of these would you like?” dialogue | Enter a number between 1-10 | Prints “You’d like {number} of these” and updates order_list. Prints "Would you like to add more to the order? [y/n]” | PASS |
"Would you like to add more to the order? [y/n]” dialogue | Enter “y” or “Y” | Prints “Choose an option (# 1-6)” | PASS |
"Would you like to add more to the order? [y/n]” dialogue | Enter “n” or “N” | Prints "What name should we write on your order?:” | PASS |
"Would you like to add more to the order? [y/n]” dialogue | Enter anything other than “y”, “Y”, “n” or “N” | Prints “Sorry, this question only accepts 'y' or 'n’. (lower case or capital)” | PASS |
"What name should we write on your order?” dialogue | Enters a string between 1-30 characters long | Sends order_list to the Google Sheet ‘orders’. Displays capitalised name, table of order, total cost, pickup time, and order time. Prints “Press ENTER to exit” | PASS |
"What name should we write on your order?” dialogue | Enters a string between less than 1 or more than 30 characters long | Prints "Please enter a name between 1-30 characters long” | PASS |
“Press ENTER to exit” | Enter “Enter” | Prints “"Thanks for using” and displays the title | PASS |
“Press ENTER to exit” | Enters any other key before pressing “Enter” | Prints "Just the 'Enter' key will do. Please press to exit.” | PASS |
- Language Used:
- Visual Studio Code - as the code editor.
- Git - for version control, using the Gitpod IDE.
- GitHub - for storing the project.
- Google Sheets - as the database.
- Heroku - to deploy the project.
- Code Institute’s Python Linter - for automated testing of the Python code.
- Code Beautify - as a code formatter.
- Diffchecker - used to compare the changes suggested by Code Beautify.
- Excalidraw - to create the flow diagrams.
- TinyPNG - to compress the Readme images.
- Ezgif - to convert the Readme GIFs.
- gspread - a Python API for Google Sheets.
- google-auth - to authenticate access to the Google Sheet.
- os - to create the
clear_screen()
function. - pyfiglet - to style the title ACSII font.
- termcolor - to add colour to text.
- time - for the
time.sleep()
function, to pause the printing of text. - sys - used alongside the time module, for the
typing_effect()
function. - tabulate - to format data into tables.
- datetime - to get the time in hours and minutes, for the
display_current_time()
function. - pytz - to get the London timezone.
By forking the GitHub Repository we make a copy of the original repository on our GitHub account to view and/or make changes without affecting the original repository by using the following steps...
- Log in to GitHub and locate the GitHub Repository
- At the top right of the Repository, just below the GitHub navbar, click on the "Fork" Button.
- You should now have a copy of the original repository in your GitHub account.
- Log in to GitHub and locate the GitHub Repository
- Above the list of files, click "Code".
- To clone the repository using HTTPS, under "Clone with HTTPS", copy the link.
- Open Git Bash
- Change the current working directory to the location where you want the cloned directory to be made.
- Type
git clone
, and then paste the URL you copied in Step 3.
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
- Press Enter. Your local clone will be created.
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
> Cloning into `CI-Clone`...
> remote: Counting objects: 10, done.
> remote: Compressing objects: 100% (8/8), done.
> remove: Total 10 (delta 1), reused 10 (delta 1)
> Unpacking objects: 100% (10/10), done.
Click Here to retrieve pictures for some of the buttons and more detailed explanations of the above process.
-
For changes you've made to reflect on the live site*:
- Type
git add <files changed>
- Type
git commit -m <description of change>
- Type
git push
*In Heroku, after pushing to Github - if 'automatic deploys' aren't enabled, manually deploy by clicking 'Deploy Branch' in the Manual Deploy section.
- Type
- Create a new spreadsheet in Google Sheets, name it ‘coffee-run’.
- Within the spreadsheet, create 2 sheets called ‘cofee_menu’ and ‘orders’.
- Within the ‘coffee_menu’ sheet, create 3 headings called ‘Coffee’, ‘Price’ and ‘#’.
- Populate the next 6 rows with your choice of coffees and prices, in the ‘#’ column, enter 1-6 in descending order [refer to the Google Sheets screenshots in the ‘Features/Display Coffee Menu’ section in this README].
- Within the ‘orders’ sheet, enter the headings ‘name’, ‘item’, ‘quantity’, ‘item’ and ‘quantity’. [refer to the Google Sheets screenshots in the ‘Features/Customer Name’ section in this README]
- Open Google Cloud.
- Click the “Select a project” button and select “new project”
- Name the project, and click “Select Project”.
- From the side menu, select "APIs and services", then select “Library”.
- Use the search bar to search for Google Drive, and select ‘API’, then ‘Enable’.
- Once redirected to the API overview page, click the “Create credentials”.
- A form appears: In the "Which API are you using" dropdown menu, select "Google Drive API".
- Select ‘web server’, then ‘application data’, and ‘no’ for the question ‘app or computer engine’
- Click “What credentials do I need?”
- Enter a service account name.
- Choose ‘Project > Editor’ in the ‘role’ selection.
- Select ‘JSON’ for the key type.
- Click ‘continue’, which will download the credentials file onto your computer.
- From the side menu, select "APIs and services", then select “Library”.
- Use the search bar to search for Google Sheets, and select ‘Google Sheets API’, then ‘Enable’.
- Locate the creds.json file that was downloaded to your computer.
- Add it to your IDE.
- Open creds.json and copy the client_email value.
- Open your Google Sheet spreadsheet and click ‘Share’.
- Paste the client_email value from the creds.json file; select “Editor”, deselect “Notify People” then click “Share”
- Make sure the “creds.json” is added to the .gitignore file within your IDE, so the authentication details aren’t uploaded to GitHub.
- Create a Heroku account.
- In the dashboard, click on ‘Create new app’ from the ‘New’ dropdown menu in the top right.
- Name the app and choose a region.
- In the ‘Settings’ tab, click on 'Reveal Config Vars’.
- In the ‘KEY’ field, write ‘CREDS’.
- In the ‘VALUE’ field, paste the contents of your ‘creds.json’ file. [Your creds.json file should be previously listed in your .gitignore file, to prevent authentication details being pushed to Github]
- Add an additional Config Var below, write ‘PORT’ for the KEY and ‘8000’ for the VALUE.
- In the 'Buildpacks' section click 'Add buildpack'.
- First, select ‘Python’, and click 'save changes'.
- Then, select ‘node.js’, and click 'save changes'.
- In the 'Deploy' tab, select GitHub as the deployment method, and click 'Connect to GitHub'.
- In the 'App Connected to GitHub' section, search for the GitHub repository name, select it then click 'connect'.
- Finally, either click ‘Enable Automatic Deploys’, or ‘Deploy Branch’ in the ‘Manual deploy’ section.
Used as inspiration:
- Clearing the terminal - appdividend.com
- The
typing_effect()
function - 101computing.net - Input validation - bobbyhadz.com
- Iterating alternatively through two lists, using the zip() function. - w3schools.com
- Converting a list of strings into a list of integers, in the
calculate_pickup_time()
function - geeksforgeeks.org - Getting the current time - programiz.com
- My mentor Brian Macharia for his invaluable guidance.