class Node:
def __init__(self, key, value):
self.key = key
self.value = value
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def search(self, key):
curr = self.head
while curr != None:
if curr.key == key:
return curr
curr = curr.next
return None
def insert(self, key, value):
node = Node(key, value)
node.next = self.head
self.head = node
def delete(self, key):
prev = None
curr = self.head
while curr != None:
if curr.key == key:
if prev == None:
self.head = curr.next
else:
prev.next = curr.next
return True
prev = curr
curr = curr.next
return False
class HashMap:
def __init__(self, capacity=16):
self.capacity = capacity
self.size = 0
self.table = [LinkedList() for _ in range(capacity)]
def _hash(self, key):
return hash(key) % self.capacity
def get(self, key):
index = self._hash(key)
node = self.table[index].search(key)
if node:
return node.value
return None
def put(self, key, value):
index = self._hash(key)
node = self.table[index].search(key)
if node:
node.value = value
else:
self.table[index].insert(key, value)
self.size += 1
if self.size > self.capacity * 0.75:
self._resize()
def delete(self, key):
index = self._hash(key)
if self.table[index].delete(key):
self.size -= 1
def _resize(self):
self.capacity *= 2
new_table = [LinkedList() for _ in range(self.capacity)]
for bucket in self.table:
curr = bucket.head
while curr != None:
index = self._hash(curr.key)
new_table[index].insert(curr.key, curr.value)
curr = curr.next
self.table = new_table</blockquote>
<pre lang="Python">import csv
from hashmap import HashMap
from math import sin, cos, sqrt, atan2
# initialize variables to store data
location_map = HashMap()
item_map = HashMap()
order_map = HashMap()
def load_location_data():
with open('location_data.csv', 'r') as file:
reader = csv.reader(file)
for row in reader:
location_name = row[0]
inventory = row[1:]
location_map[location_name] = inventory
def load_order_data():
with open('order_data.csv', 'r') as file:
reader = csv.reader(file)
for row in reader:
order_id = row[0]
locations = row[1:]
order_map[order_id] = locations
def load_serialised_data():
with open('serialised_data.csv', 'r') as file:
reader = csv.reader(file)
for row in reader:
location_name = row[0]
item = row[1]
quantity = int(row[2])
if location_name not in item_map:
item_map[location_name] = {}
item_map[location_name][item] = quantity
def find_location_inventory():
location_name = input("Enter location name: ")
inventory = location_map[location_name]
print(f"Location inventory for {location_name}:")
for item in inventory:
print(item)
def find_distance():
start_location = input("Enter starting location: ")
end_location = input("Enter ending location: ")
start_coords = tuple(float(x) for x in location_map[start_location][:2])
end_coords = tuple(float(x) for x in location_map[end_location][:2])
# calculate distance using Haversine formula
earth_radius = 6371.01 # km
lat1, lon1 = start_coords
lat2, lon2 = end_coords
delta_lat = lat2 - lat1
delta_lon = lon2 - lon1
a = (sin(delta_lat / 2)) ** 2 + cos(lat1) * cos(lat2) * (sin(delta_lon / 2)) ** 2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = earth_radius * c
print(f"Distance from {start_location} to {end_location}: {distance:.2f} km")
def find_order_route():
order_id = input("Enter order ID: ")
locations = order_map[order_id]
print(f"Route for order {order_id}:")
total_distance = 0
for i in range(len(locations) - 1):
start_location = locations[i]
end_location = locations[i + 1]
start_coords = tuple(float(x) for x in location_map[start_location][:2])
end_coords = tuple(float(x) for x in location_map[end_location][:2])
# calculate distance using Haversine formula
earth_radius = 6371.01 # km
lat1, lon1 = start_coords
lat2, lon2 = end_coords
delta_lat = lat2 - lat1
delta_lon = lon2 - lon1
a = (sin(delta_lat / 2)) ** 2 + cos(lat1) * cos(lat2) * (sin(delta_lon / 2)) ** 2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = earth_radius * c
total_distance += distance
print(f"From {start_location} to {end_location}: {distance:.2f} km")
print(f"Total distance for order {order_id}: {total_distance:.2f} km")
def location_overview():
print("Location overview:")
for location, items in location_map.items():
print(f"{location}: {len(items)} items in inventory")
def inventory_overview(inventory):
total_items = 0
total_value = 0
for item, info in inventory.items():
total_items += info['quantity']
total_value += info['price'] * info['quantity']
print(f"{item.capitalize()}: {info['quantity']} units, ${info['price']} each")
print(f"\nTotal number of items: {total_items}")
print(f"Total value of inventory: ${total_value}")
def save_data():
with open('serialised_data.csv', 'w', newline='') as file:
writer = csv.writer(file)
for loc, items in item_map.items():
for item, quantity in items.items():
writer.writerow([loc, item, quantity])
print("Data saved successfully")
# menu loop
while True:
print("Welcome to the Interactive Menu:")
print("1. Load data")
print("2. Find and display location Inventory")
print("3. Find and dislpay distance between two locations")
print("4. Find and display route for collecting order")
print("5. Location Overview")
print("6. Inventory Overview")
print("7. Save data")
print("8. Exit")
choice = input("Select which option you would like to choose: ")
if choice == "1":
load_location_data()
load_order_data()
load_serialised_data()
print("Data successfully loaded")
elif choice == "2":
find_location_inventory()
elif choice == "3":
find_distance()
elif choice == "4":
find_order_route()
elif choice == "5":
location_overview()
elif choice == "6":
inventory_overview()
elif choice == "7":
save_data()
print("Data saved successfully")
elif choice == "8":
#code for option8
print("Exiting the interactive menu")
break
else:
print("Invalid option was selected")
What I have tried:
The HashMap function wasn't originally written using linked lists, but the same errors were still present. I rewrote the code using a linked list to factor in the collisions that would be caused, but the same errors persisted. The main goal of the code is to make the interactive menu work by displaying the information that gets imported by the CSV files. Whenever I run the interactive menu and choose an option to run, I either get an attribute error or a typeerror that is associated with the HashMap file. I have tried rewriting the code in different forms but the same problem keeps coming back.
The following is what is in the CSV files.
location_data:
"Location name", "products", "distance"
"Location A", "Item 1, Item 2, Item 3, Item 4", "40.7128, -74.2312"
"Location B", "Item 1, Item 2", "35.2321, -83.2415"
"Location C", "Item 1, Item 2, Item 3", "41.1633, -52.2352"
"Location D", "Item 1, Item 2, Item 3, Item 4, Item 5", "32.2512, -85.3425"
order_data:
"Order ID", "Order route"
"Order 1", "Location A, Location B"
"Order 2", "Location A"
"Order 3", "Location B, Location C"
"Order 4", "Location C, Location A, Location D"
serialised_data:
"Location", "Items", "Quantity"
"Location A", "Item 1", "4"
"Location A", "Item 2", "5"
"Location B", "Item 5", "2"
"Location C", "Item 2", "7"
"Location D", "Items 4", "9"
"Location D", "Item 3", "10"