import time
import sys
class TravelSimulator:
"""
Professional Travel Speed Simulator.
Calculates travel times for Walking, Biking, and Driving.
"""
# Average speeds in km/h
SPEEDS = {
"Walking": 5.0,
"Cycling": 20.0,
"Driving": 60.0
}
ICONS = {
"Walking": "🚶",
"Cycling": "🚲",
"Driving": "🚗"
}
def __init__(self, distance: float, unit: str = "km"):
self.distance_input = distance
self.unit = unit.lower()
self.distance_km = self._convert_to_km(distance, unit)
def _convert_to_km(self, dist: float, unit: str) -> float:
"""Converts miles to km if necessary."""
if unit.startswith("mi"):
return dist * 1.60934
return dist
def calculate_times(self):
"""Calculates duration in hours for each mode."""
results = {}
for mode, speed in self.SPEEDS.items():
hours = self.distance_km / speed
results[mode] = hours
return results
def format_duration(self, hours_decimal: float) -> str:
"""Formats decimal hours into readable H:M format."""
total_minutes = int(round(hours_decimal * 60))
hours = total_minutes // 60
minutes = total_minutes % 60
if hours == 0:
return f"{minutes} min"
return f"{hours}h {minutes}m"
def run_simulation(self):
"""Runs a text-based visualization of the race."""
results = self.calculate_times()
print(f"\n--- 🏁 TRAVEL SIMULATION: {self.distance_input} {self.unit} ---\n")
# Sort by slowest to fastest for the calculation logic
# (Though we display them in standard order)
modes = ["Walking", "Cycling", "Driving"]
print(f"{'MODE':<10} | {'SPEED (Avg)':<15} | {'EST. TIME'}")
print("-" * 45)
for mode in modes:
speed_display = f"{self.SPEEDS[mode]} km/h"
time_str = self.format_duration(results[mode])
print(f"{self.ICONS[mode]} {mode:<7} | {speed_display:<15} | {time_str}")
print("\n--- Visual Comparison ---")
self._animate_bars(results)
def _animate_bars(self, results):
"""Simulates the race with a progress bar."""
# Normalize durations: Longest time (Walking) is the baseline
max_time = results["Walking"]
width = 40 # Character width of the bar
# Calculate relative speeds (inverse of time) for the animation step
# Faster modes fill up faster.
progress = {mode: 0 for mode in results}
completed = {mode: False for mode in results}
print("Simulating...")
while not all(completed.values()):
sys.stdout.write("\033[F" * 4) # Move cursor up 4 lines
for mode in ["Walking", "Cycling", "Driving"]:
if not completed[mode]:
# Speed factor: How much of the bar to fill per tick
# This logic makes faster modes fill the bar faster relative to walking
step = (max_time / results[mode]) * 0.5
progress[mode] += step
if progress[mode] >= width:
progress[mode] = width
completed[mode] = True
bar_fill = int(progress[mode])
bar = "█" * bar_fill + "░" * (width - bar_fill)
status = "DONE" if completed[mode] else "RUNNING"
print(f"{mode:<8} [{bar}] {status}")
time.sleep(0.05)
print("\nDone! 🏁")
if __name__ == "__main__":
try:
# Simple CLI Input
print("Professional Speed Calculator")
d_input = float(input("Enter distance: "))
u_input = input("Unit (km/mi): ").strip()
sim = TravelSimulator(d_input, u_input)
sim.run_simulation()
except ValueError:
print("Error: Please enter a valid number for distance.")