Coders Parkhouse is a Python Terminal Application which should simulate a real life situation of using a parking lot. There is a little twist to it, to make it a little bit more entertaining.
Coders Parkhouse live project here.
- Welcome to Coders Parkhouse
- Park the car
- Entering Registration Number
- Paying Debt/Actually Mistake
- Parking Duration(Hours)
- Return/NotYet
- Leave Parking Lot
- Parking Details
- Time of Arrival
- Discount Code
- Pay at Exit
- Further Improvements
Using of this application is pretty straight forward as it would be to use parking lot services in real life. Driver/User is greeted with the ASCII art at the entrance letting the driver know where he is.
-
User/Driver goals
- Be able to enter/leave parking lot.
- Be able to see the prices at the entrance.
- Be able to park for cheap price.
- Be able to use automated parking system.
- Be able to understand instructions easily.
- Be able to enter registration into predetermined template.
- Be able to know time(duration) of parking.
- Be able to know total cost of the parking.
- Be able to get some discount. :)
-
Creator/Owner goals
- Present own services in understandable manner.
- Instuctions to be intuitive.
- Handle possible invalid inputs from customers.
- Prices to be competitive.
- Offer to the user to reject if he isn't satisfied with the prices.
- Track the time spent on the parking lot.
- Calculating the price automatically according to the time spent.
- Have the track of the cars on the lot.
- Have the track of previous debts of certain cars(imaginary).
- Be kind to the customers.
- Be able to offer small discount to the customers.
-
Initial Flowcharts
-
Flowcharts used as a base for development process.
-
-
Final Flowcharts
-
Flowcharts after all desired functions were implemented.
-
When you go to Coders Parkhouse, this is what is waiting for you.
At the entrance/exit you are being greeted and two options are being given to you:
- To park the car.
- To leave the parking lot.
-
If you choose to park the car, the rules of the parking house are being displayed to you. You are also being asked if you agree to the terms of use, which you can accept or reject and search for a better place to park.
-
If you reject the terms of use, you will be greeted nicely.
-
If you accept and you do want to park here, you will be taken to the next step.
-
Here you must enter your registration number but according to one of the four given patterns. Instructions are telling you to use letters, digits and dashes only, other characters will trigger Invalid Input.
-
In case you use valid pattern for your registration number, you can have 2 scenarios:
-
You type in valid registration number and you can go further to enter the parking duration.
-
You type in valid registration number, but you find out there is a debt from the last time, which you need to take care of, so that you can park here again. Behind the scenes the code is checking if the given registration is already inside the google sheet. In this case it is, which represents your "debt".
-
-
You have 2 options here, to pay your debt to be able to park again or to type in your registration number again because actually it was a typo.
-
If you choose to pay your debt, after the transaction is over, you will be able to enter your registration number again and park as you wish. In reality the reg. number is getting deleted from the google sheet, so you are able to enter with the same registration again.
-
If you actually made a mistake and you choose "new". You will be taken back to enter your registration number again.
-
-
When we manage to pay off our dept (^.-) and we enter the valid reg. number, we need to enter number of hours or let's say duration of our parking. In this case the number is unlimited.
-
In the background there is a list in program which holds the registration number, number of hours and price which is calculated according to the hours we enter.
-
Price is calculated as: Hours * 3euro
-
At this moment the list is being inserted/written into the google sheet.
-
In this step the info about our parking is being presented to us.
-
After we are presented with the info in the end, we have two options:
-
After we come back to pick up our car, either by entering "return" at the end of our parking process or by restarting the program and we choose the option number two, to leave the parking lot, we need to enter our registration number again.
-
By entering our reg. number again, the system is checking if the reg. number is in the google sheet(did we park here at all).
-
Here we are going to have 2 options.
-
First one where the registration number is valid but car is not parked at our parking lot(not present in the google sheet).
-
Second option, where registration number is valid and is parked at our parking lot(is present in the google sheet).
-
Registration Not Existing
-
Here we have 2 scenarios again, where the driver will be able to type in the reg. number again in case he made a typo or he can freely walk away in case he missed the parking lot(^_^).
-
Registration Existing
-
-
When we enter registration number which is present in our system, we are getting full initial details about our parking.
-
In the background the system is reading from the google sheet and pulling the row according to the registration number.
-
After that we can choose between three possible scenarios, which represent our time of arrival.
-
According to the option we choose here, our price will be calculated. Meaning if we choose Earlier or On Point the price will actually be the same as the initial one, while if we choose Later, a fee of 10€ will be added to the initial price(the price here is calculated accodring to our parking rules).
-
Earlier/On Point
-
Later
-
Suddenly the driver will be asked if he knows about the CI discount code, to get 10% off of the final price.
-
Here we will have two scenarios, where driver will know the code or he wouldn't. The Driver will be answered in a funny manner, according to the scenario.
-
In the end, we are prompted to pay the final price we got.
-
There will be 2 scenarios again, where we can choose between "pay" or anything else.
-
In order to exit the parking lot, we must choose "pay" in the end.
- Add coloring for Valid/Invalid inputs, green/red for example, for better UX(lack of time).
- Improve system to track time automatically, which will eleminate need of the given 3 scenarios(earlie, on point, late).
- Improve parking system to track real date/time(real life application).
- Improve pricing system in case people want to leave their cars for a longer period of time. Maybe give some better options for those who want to park for a longer period(days, weeks...), since at the moment this option is simple number of hours and is unlimited(real life application).
- Add cameras to replace manual input of registration number(real life application).
- Add printer which will print out cards with the registration number, time and date. Those cards would be needed at the exit, at the payment process(real life application).
- Python
- JavaScript (used by template creator)
- HTML (used by template creator)
- gspread
- Google API for GoogleSheets.
- google.oauth2.service_account
- System used for server-to-server interactions.
- regex
- Regular Expression used for setting up patterns.
- Git
- Used for version control, commit to Git and Push to GitHub.
- GitHub
- Used to store the code online and for deployment.
- Gitpod
- Used for development as a cloud IDE.
- Heroku
- Used to deploy the project.
- drawio
- Used to create Flowcharts.
- PEP8CI - Python Linter
- Used to validate Python code.
- Am I Responsive
- Used to create mockup image for the README file.
- Text to ASCII Art Generator
- Used to create ASCII art for welcoming and farewell messages.
Software used to validate the Pythone code is PEP8CI - Python Linter, mentioned in the Frameworks and Other Programs section above.
-
Before:
-
After:
| Feature | User Input/State | Output | Result |
|---|---|---|---|
| Application Loads | No Input | Welcoming menu is presented. | Confirmed |
| Welcoming Options | 1 | Driver chooses to park. | Confirmed |
| Welcoming Options | 2 | Driver chooses to leave. | Confirmed |
| Welcoming Options | 3 | That's not an option! | Confirmed |
| Welcoming Options | # | You must choose between numbers 1 and 2. | Confirmed |
| Welcoming Options | Any special character | You must choose between numbers 1 and 2. | Confirmed |
| Parking Rules | yes | Proceeds to registration entry. | Confirmed |
| Parking Rules | no | Farewell message | Confirmed |
| Parking Rules | 1 | Please answer with yes or no. | Confirmed |
| Parking Rules | # | Please answer with yes or no. | Confirmed |
| Parking Rules | Empty space | Please answer with yes or no. | Confirmed |
| Parking Rules | Any special character | Please answer with yes or no. | Confirmed |
| Reg. Number Input | XY-123-XY | Reg. number is valid.(if not in system already) | Confirmed |
| Reg. Number Input | XY-1234-XY | Reg. number is valid.(if not in system already) | Confirmed |
| Reg. Number Input | XYZ-123-XY | Reg. number is valid.(if not in system already) | Confirmed |
| Reg. Number Input | XYZ-1234-XY | Reg. number is valid.(if not in system already) | Confirmed |
| Reg. Number Input | XY-123-XY | Reg. number is already in our system!(if it is present in the system aleady) | Confirmed |
| Reg. Number Input | XY-1234-XY | Reg. number is already in our system!(if it is present in the system aleady) | Confirmed |
| Reg. Number Input | XYZ-123-XY | Reg. number is already in our system!(if it is present in the system aleady) | Confirmed |
| Reg. Number Input | XYZ-1234-XY | Reg. number is already in our system!(if it is present in the system aleady) | Confirmed |
| Reg. Number Input | XY-12345-XY | Please use one of the given patterns. | Confirmed |
| Reg. Number Input | XYZABC-12345-ZZXY | Please use one of the given patterns. | Confirmed |
| Reg. Number Input | XY- 1 2 3-XY | Please use one of the given patterns. | Confirmed |
| Reg. Number Input | 123-123-123 | Sorry, Invalid Input! | Confirmed |
| Reg. Number Input | # | Sorry, Invalid Input! | Confirmed |
| Reg. Number Input | Empty space | Sorry, Invalid Input! | Confirmed |
| Reg. Number Input | XY-123-XY!^$@ | Sorry, Invalid Input! | Confirmed |
| Pay Debt/ New | pay | Paying...Ok now you can park here again. | Confirmed |
| Pay Debt/ New | new | Back to Registration Number Input. | Confirmed |
| Pay Debt/ New | no | Invalid Input! Sorry but "no" is not an option! | Confirmed |
| Pay Debt/ New | # | Invalid Input! Sorry but "#" is not an option! | Confirmed |
| Pay Debt/ New | new1 | Invalid Input! Sorry but "new1" is not an option! | Confirmed |
| Pay Debt/ New | Empty space | Invalid Input! Sorry but " " is not an option! | Confirmed |
| Number of Hours | 0 | Zero is not an option, sorry. | Confirmed |
| Number of Hours | 0.2 | Use only didigts 0-9, only whole numbers please. No special signs neither. | Confirmed |
| Number of Hours | # | Use only didigts 0-9, only whole numbers please. No special signs neither. | Confirmed |
| Number of Hours | ! | Use only didigts 0-9, only whole numbers please. No special signs neither. | Confirmed |
| Number of Hours | Empty space | Use only didigts 0-9, only whole numbers please. No special signs neither. | Confirmed |
| Number of Hours | Any special character | Use only didigts 0-9, only whole numbers please. No special signs neither. | Confirmed |
| Number of Hours | python | Use only didigts 0-9, only whole numbers please. No special signs neither. | Confirmed |
| Number of Hours | 1 | Very well! Try not to be late, otherwise it will be more expensive. | Confirmed |
| Number of Hours | 5 | Very well! Try not to be late, otherwise it will be more expensive. | Confirmed |
| Number of Hours | 999 | Very well! Try not to be late, otherwise it will be more expensive. | Confirmed |
| Return/Not Yet | # | Invalid Input! | Confirmed |
| Return/Not Yet | Empty space | Invalid Input! | Confirmed |
| Return/Not Yet | 1 | Invalid Input! | Confirmed |
| Return/Not Yet | mama | Invalid Input! | Confirmed |
| Return/Not Yet | Any special character | Invalid Input! | Confirmed |
| Return/Not Yet | return_ | Invalid Input! | Confirmed |
| Return/Not Yet | return | Welcoming menu is presented. | Confirmed |
| Return/Not Yet | not yet | Ok, see ya later! | Confirmed |
| Reg. Number Input / Leaving parking lot | Empty space | Invalid data, please use correct pattern. | Confirmed |
| Reg. Number Input / Leaving parking lot | 123 | Invalid data, please use correct pattern. | Confirmed |
| Reg. Number Input / Leaving parking lot | # | Invalid data, please use correct pattern. | Confirmed |
| Reg. Number Input / Leaving parking lot | Any special character | Invalid data, please use correct pattern. | Confirmed |
| Reg. Number Input / Leaving parking lot | XY-__123__-XY | Invalid data, please use correct pattern. | Confirmed |
| Reg. Number Input / Leaving parking lot | XY-123-XY | Registration number is valid but not in our system. Are you sure that you parked here?(if not present in the system) | Confirmed |
| Reg. Number Input / Leaving parking lot | XYZ-1234-XY | Registration number is valid but not in our system. Are you sure that you parked here?(if not present in the system) | Confirmed |
| Reg. Number Input / Leaving parking lot | XYZ-1234-XY | Valid Input! Details loading...(if reg. number is present in the system) | Confirmed |
| Reg. Number Input / Leaving parking lot | AA-123-BC | Valid Input! Details loading...(if reg. number is present in the system) | Confirmed |
| Reg. Number Valid but not in system.(Yes/No) | ! | Please answer with "yes" or "no". | Confirmed |
| Reg. Number Valid but not in system.(Yes/No) | # | Please answer with "yes" or "no". | Confirmed |
| Reg. Number Valid but not in system.(Yes/No) | 123 | Please answer with "yes" or "no". | Confirmed |
| Reg. Number Valid but not in system.(Yes/No) | Any special character | Please answer with "yes" or "no". | Confirmed |
| Reg. Number Valid but not in system.(Yes/No) | !yes | Please answer with "yes" or "no". | Confirmed |
| Reg. Number Valid but not in system.(Yes/No) | No% | Please answer with "yes" or "no". | Confirmed |
| Reg. Number Valid but not in system.(Yes/No) | +yes | Please answer with "yes" or "no". | Confirmed |
| Reg. Number Valid but not in system.(Yes/No) | yes | We need your registration number please. | Confirmed |
| Reg. Number Valid but not in system.(Yes/No) | no | Have a nice day! Until the next time! | Confirmed |
| Time of arrival (Options: 1, 2 or 3) | # | Invalid Input! | Confirmed |
| Time of arrival (Options: 1, 2 or 3) | 4 | That's not an option. | Confirmed |
| Time of arrival (Options: 1, 2 or 3) | 0.5 | Invalid Input! | Confirmed |
| Time of arrival (Options: 1, 2 or 3) | Empty space | Invalid Input! | Confirmed |
| Time of arrival (Options: 1, 2 or 3) | -1 | That's not an option. | Confirmed |
| Time of arrival (Options: 1, 2 or 3) | +1 | Don't use prefix plus. | Confirmed |
| Time of arrival (Options: 1, 2 or 3) | 1 | Your final price should be X€. | Confirmed |
| Time of arrival (Options: 1, 2 or 3) | 2 | Your final price should be X€. | Confirmed |
| Time of arrival (Options: 1, 2 or 3) | 3 | Your final price should be X€. | Confirmed |
| Discount Code | 123 | Looks like your boss doesn't like you so much. :( | Confirmed |
| Discount Code | # | Looks like your boss doesn't like you so much. :( | Confirmed |
| Discount Code | Empty space | Looks like your boss doesn't like you so much. :( | Confirmed |
| Discount Code | Any special character | Looks like your boss doesn't like you so much. :( | Confirmed |
| Discount Code | CI2023/ci2023 | Looks like your boss likes you. :) | Confirmed |
| Pay at Exit | 0 | Sorry, until you pay, you can't drive out! :) | Confirmed |
| Pay at Exit | # | Sorry, until you pay, you can't drive out! :) | Confirmed |
| Pay at Exit | Empty space | Sorry, until you pay, you can't drive out! :) | Confirmed |
| Pay at Exit | Empty space + "pay" | Sorry, until you pay, you can't drive out! :) | Confirmed |
| Pay at Exit | pay_ | Sorry, until you pay, you can't drive out! :) | Confirmed |
| Pay at Exit | pay+ | Sorry, until you pay, you can't drive out! :) | Confirmed |
| Pay at Exit | Any special character | Sorry, until you pay, you can't drive out! :) | Confirmed |
| Pay at Exit | pay | Paying...Complete! Have a nice day! Until next time! | Confirmed |
-
Bug 1:
-
Multiple lists written into the google sheet, after the driver would "return" and use same registration in the registration input section, after paying the debt off.
-
-
Fix 1:
-
This was sorted with clear() method on the list which holds the driver details, before "return" part of the application.
-
-
Bug 2:
-
In the Time of Arrival part of program, when user has to choose between options Earlier, On Point and Later, by inputing 1, 2, or 3. The program would accept multiple empty spaces before and after 1, 2, or 3.
-
-
Fix 2:
-
It was sorted out by using len() method on the real_duration string, and if statement insuring that it's lenght is not bigger than 1.
-
-
Bug 3:
-
While entering the registration number in case of parking or leaving the parking lot, the program would accept registration as valid as long as it would contain the number of correct pattern even if before and after the registration number would be special characters.
-
For example: ###XY-123-XY%%% would be accepted, ___XYZ-1234-XY//.#@ would be accepted and so on...
-
-
Fix 3:
-
This was fixed by adding the special characters for start and end of the pattern within the string, which represents my registration numbers pattern.('^---pattern---$')
-
-
At the moment there are no known bugs.
-
The only thing I can mention is that terminal which runs the code on the Heroku, is not responsible. It means if we reduce the width of the browser the terminal will get covered. That has nothing to do with the project itself.
-
Go to Heroku, create account if you don't have and log in.
-
Head to your dashboard and click "New", then "Create new app"
-
Next step is to give your app a name and to choose region. After that click on "Create app".
-
After that head to "Settings" tab which you can find on top of your Heroku page and under the "Config Vars" set your Key/Value Pairs.
-
Then in the "Buildpacks" section you will need to add buildpacks. Pay attention to the order in which you add buildpacks you need. In my case I had to add Python first and nodejs second.
-
First add "Python", by clicking on Python icon and then click on "Add Buildpack".
-
Then add "nodejs", by clicking on nodejs icon and then click on "Add Buildpack".
-
Then head to "Deployment" tab which you can also find on top of your Heroku page and under "Deployment method" click on "GitHub"(in my case that's where my repository is).
-
After that, just under the "Deployment method" section is "Connect to GitHub" section where you need to find your repository and then click on "Connect".
-
Just under "Connect to GitHub" section is "Automatic deploys" section where you can click on "Enable Automatic Deploys" if that's what you want and just under is "Manual Deploy" section, where you need to click on "Deploy Manually".
By forking the GitHub Repository we can make a copy of the original repository to view or make changes without changing the original repository.
- Log in to GitHub and locate Coders Parkhouse
- At the top, in the line with the project's name, on the right side find "Fork", click.
- Now you have a copy of the original repository in your GitHub account.
-
I want to say to my wife:"Thank you for all your love and support."
-
I want to thank to my mentor Mitko Bachvarov for tips and suggestions.
-
Love Sandwiches project inspired me to include google sheets.
-
REGEX WITH EXAMPLES IN DETAIL contributed a lot to my understanding of regular expressions.
-
Sites which contributed to development of this application:
-
Readme files which were used as inspiration:











































