Skip to content

Commit f3354be

Browse files
Feat: Added add_itinerary functionality to main program (main.py) and function handler (manage_itineraries.py). Also added requirements.txt for pip install.
1 parent 55d26c9 commit f3354be

3 files changed

Lines changed: 185 additions & 17 deletions

File tree

Travel Itinerary Planner/main.py

Lines changed: 84 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,48 +10,115 @@ def user_task_request(request, itinerary_list):
1010
if request == "1":
1111
flights_list_done = False
1212
attractions_list_done = False
13+
1314
print("How exciting! Please provide us information about the trip: \n")
1415
name = input("Title of the itinerary: ")
1516
location = input("Location (NA if not applicable): ")
1617
summary = input("Brief description of trip: ")
1718
start_date = input("Start date in DD-MM-YYYY: ")
1819
end_date = input("End date in DD-MM-YYYY: ")
19-
while not flights_list_done:
20-
# Answer format: Perth-Sydney 12-12-2012, Sydney-Perth 21-12-2012
21-
flights = input("") # dictionary - add loop here
22-
if flights == "DONE":
23-
flights_list_done = True
24-
while not attractions_list_done:
25-
attractions = input("") # dictionary - add loop here
26-
if attractions == "DONE":
27-
attractions_list_done = True
20+
flights = {}
21+
attractions = {}
22+
23+
print("\nNow it is time to add flights!")
24+
user_flight_choice = input("If you want to skip this step, type SKIP and press 'Enter'. Otherwise, press 'Enter'. ")
25+
flights_list_done = False
26+
27+
if user_flight_choice == "SKIP":
28+
flights = {}
29+
else:
30+
while not flights_list_done:
31+
flight_details = {}
32+
33+
departure_airport = input("Name of the airport you will depart from: ")
34+
departure_date = input("Date & time of flight departure (Format: DD-MM-YYYY HH:MM): ")
35+
arrival_airport = input("Name of the airport you will arrive at: ")
36+
arrival_date = input("Date & time of flight arrival (Format: DD-MM-YYYY HH:MM): ")
37+
flight_name = f"{departure_airport} to {arrival_airport}"
38+
39+
flight_details.update({
40+
"departure airport": departure_airport,
41+
"departure date": departure_date,
42+
"arrival airport": arrival_airport,
43+
"arrival date": arrival_date
44+
})
45+
flights[flight_name] = flight_details
46+
47+
add_another_flight = input("Would you like to add another flight? Type Y (yes) or N (no): ")
48+
while True:
49+
if add_another_flight == "Y":
50+
flights_list_done = True
51+
break
52+
elif add_another_flight == "N":
53+
flights_list_done = False
54+
break
55+
else:
56+
print("Invalid answer: Please type Y or N only.")
57+
58+
print("\nFinally: ATTRACTIONS!")
59+
user_attractions_choice = input("If you want to skip this step, type SKIP and press 'Enter'. Otherwise, press 'Enter'. ")
60+
attractions_list_done = False
61+
62+
if user_attractions_choice == "SKIP":
63+
attractions = {}
64+
else:
65+
while not attractions_list_done:
66+
attraction_details = {}
67+
68+
attraction_name = input("Name of attraction: ")
69+
attraction_address = input("Address of attraction: ")
70+
attraction_summary = input("Short description of attraction: ")
71+
attraction_type = input("(Optional) Provide some tags that categorise what kind of activity this involves.\nExample of format required: hike, exciting, views\n")
72+
attraction_tags = attraction_type.split(", ")
73+
74+
attraction_details.update({
75+
"address": attraction_address,
76+
"summary": attraction_summary,
77+
"tag(s)": attraction_tags
78+
})
79+
attractions[attraction_name] = attraction_details
80+
81+
add_another_attraction = input("Would you like to add another attraction? Type Y or N:")
82+
while True:
83+
if add_another_attraction == "Y":
84+
attractions_list_done = True
85+
break
86+
elif add_another_attraction == "N":
87+
attractions_list_done = False
88+
break
89+
else:
90+
print("Invalid answer: Please type Y or N only.")
91+
2892
add_itinerary(itinerary_list, name, location, summary, start_date, end_date, flights, attractions)
29-
pass
3093

3194
# Edit existing itinerary
3295
elif request == "2":
3396
# Use pickpack module (https://github.com/anafvana/pickpack#map-function-for-nested-lists)
97+
chosen_itinerary = input("")
98+
edit_itinerary(itinerary_list, chosen_itinerary)
3499
pass
35-
100+
36101
# View itinerary
37102
elif request == "3":
38-
view_itineraries(itinerary_list)
103+
chosen_itinerary = input("")
104+
view_itineraries(itinerary_list, chosen_itinerary)
39105
pass
40106

41107
# Delete itinerary
42108
elif request == "4":
43-
delete_itinerary(itinerary_list)
109+
chosen_itinerary = input("")
110+
delete_itinerary(itinerary_list, chosen_itinerary)
44111
pass
45112

113+
# Export itinerary
46114
elif request == "5":
47-
# Export to .csv file?
48-
# Use pick (not pickpack) library to list itineraries by name and location
49-
export_itinerary(itinerary_list)
115+
chosen_itinerary = input("")
116+
export_itinerary(itinerary_list, chosen_itinerary)
50117
pass
51118

52119
else:
53120
print("Invalid answer, please type a number between 1-5.")
54-
pass
121+
return
55122

56123

57124
def run_app():
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
flake8==7.3.0
2+
pick==v2.4.0
3+
pickpack==2.0.0
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
from src.itinerary import Itinerary
2+
from datetime import datetime
3+
4+
"""
5+
This file contains all of the functions needed for the Travel Itinerary Planner.
6+
It allows the user to add, edit, view, delete, and export an itinerary while checking for errors in input.
7+
"""
8+
9+
10+
def add_itinerary(itinerary_list, name, location, summary, start_date, end_date, flights, attractions):
11+
"""
12+
Add a new itinerary to the list of itineraries.
13+
14+
Args:
15+
itinerary_list (list): The list of existing Itinerary objects.
16+
location (str): The main city/country the holiday takes place.
17+
summary (str, optional): A brief summary of the travel plan.
18+
start_date (str): The date the holiday begins in 'DD-MM-YYYY' format.
19+
end_date (str): The date the holiday ends in 'DD-MM-YYYY' format.
20+
flights (nested dict): A nested dictionary type. Flight name (before-after location format, e.g. Perth-Sydney) is tied to a date in 'DD-MM-YYYY' format.
21+
attractions (nested dict): Dictionary of attractions. Each dictionary key (name of attraction) contains a short description of the attraction (object).
22+
23+
Returns:
24+
bool: True if Itinerary is added without issue, otherwise False.
25+
26+
Raises:
27+
ValueError: If the start or end date is not in the correct format.
28+
29+
Side Effects:
30+
- Saves the updated itinerary list to a file using `update_itinerary`.
31+
"""
32+
# Prevent duplicate itineraries
33+
if any(trip.name == name for trip in itinerary_list):
34+
print("Error: A trip with this name already exists!")
35+
return False
36+
37+
if not validate_dates(start_date, end_date, flights):
38+
return False
39+
40+
# Add the new itinerary after validation checks
41+
itinerary_list.append(Itinerary(name, location, summary, start_date, end_date, flights, attractions))
42+
43+
44+
def edit_itinerary(itinerary_list, chosen_itinerary):
45+
# Use pickpack module (https://github.com/anafvana/pickpack#map-function-for-nested-lists)
46+
pass
47+
48+
49+
def view_itineraries(itinerary_list, chosen_itinerary):
50+
if not itinerary_list:
51+
print("No itineraries planned!")
52+
else:
53+
# Use pick module: Ask if they would like to view all itineraries, or a specific one
54+
pass
55+
return
56+
57+
58+
def delete_itinerary(itinerary_list, chosen_itinerary):
59+
print("What would you like to delete?")
60+
# Use pickpack module (https://github.com/anafvana/pickpack#map-function-for-nested-lists)
61+
pass
62+
63+
64+
def export_itinerary(itinerary, chosen_itinerary):
65+
# Export to .pdf or .csv file
66+
# Use pick (not pickpack) library to list itineraries by name and location
67+
pass
68+
69+
70+
# Validation functions
71+
72+
def validate_dates(start_date, end_date, flights):
73+
# Validate dates given for start date, end date and flight datetimes
74+
try:
75+
datetime.strptime(start_date, "%d-%m-%Y")
76+
except ValueError:
77+
print("Error: Invalid start date. Use 'DD-MM-YYYY' format.")
78+
return False
79+
80+
try:
81+
datetime.strptime(end_date, "%d-%m-%Y")
82+
except ValueError:
83+
print("Error: Invalid end date. Use 'DD-MM-YYYY' format.")
84+
return False
85+
86+
# Resource used for following code: https://stackoverflow.com/questions/17322208/multiple-try-codes-in-one-block
87+
for flight_name, flight_info in flights.items():
88+
try:
89+
datetime.strptime(flight_info["departure_time"], "%d-%m-%Y %H:%M")
90+
except ValueError:
91+
print("Error: Invalid date/time for flight departure. Use 'DD-MM-YYYY HH:MM' format.")
92+
return False
93+
94+
try:
95+
datetime.strptime(flight_info["arrival_time"], "%d-%m-%Y %H:%M")
96+
except ValueError:
97+
print("Error: Invalid date/time for flight arrival. Use 'DD-MM-YYYY HH:MM' format.")
98+
return False

0 commit comments

Comments
 (0)