Skip to content

Commit 5207c8d

Browse files
authored
Merge pull request #42 from naylin-dev/main
add geographic distance and estimated travel time calculator
2 parents a2d9765 + 2340445 commit 5207c8d

File tree

5 files changed

+207
-0
lines changed

5 files changed

+207
-0
lines changed

Geographic Distance/README.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Geographic Distance and Travel Time Calculator
2+
3+
This Python script calculates the geodesic distance between two geographic coordinates and estimates travel time based on a given average speed. It uses the geopy library to compute distances.
4+
5+
## Features
6+
7+
- Input coordinates for two locations (latitude and longitude) interactively.
8+
- Calculate the distance between the two coordinates in kilometers.
9+
- Estimate the travel time based on a given average speed (in km/h).
10+
11+
## Prerequisites
12+
13+
- Python 3.x installed on your system.
14+
15+
## Setup
16+
17+
1. Clone the repository
18+
19+
```bash
20+
git clone https://github.com/king04aman/All-In-One-Python-Projects.git
21+
cd All-In-One-Python-Projects/Geographic Distance
22+
```
23+
24+
2. Create and activate a virtual environment
25+
26+
- For macOS/Linux:
27+
28+
```bash
29+
python3 -m venv venv
30+
source venv/bin/activate
31+
```
32+
33+
- For Windows:
34+
35+
```bash
36+
python -m venv venv
37+
venv\Scripts\activate
38+
```
39+
40+
3. Install the required dependencies
41+
42+
The required packages are listed in requirements.txt. Install them using the following command:
43+
44+
```bash
45+
pip install -r requirements.txt
46+
```
47+
48+
Note: The main dependency is geopy for calculating distances based on geodesic coordinates.
49+
50+
## Usage
51+
52+
1. Run the script:
53+
54+
```bash
55+
python geographic_distance.py
56+
```
57+
58+
2. Enter the coordinates (latitude and longitude) of the two locations when prompted.
59+
3. Enter the average speed in km/h to calculate the travel time.
60+
61+
Example input:
62+
63+
```
64+
Enter the latitude and longitude of the first location (lat1, lon1) Example: 40.7128, -74.006: 52.5200, 13.4050
65+
Enter the latitude and longitude of the second location (lat2, lon2) Example: 37.7749, -122.4194: 48.8566, 2.3522
66+
Enter the average speed in km/h Example: 60: 80
67+
```
68+
69+
Example output:
70+
71+
```
72+
Distance between the two coordinates: 878.84 kilometers
73+
Estimated travel time: 10.99 hours
74+
```
75+
76+
## Requirements
77+
78+
Here’s a list of Python dependencies in requirements.txt:
79+
80+
```
81+
geopy==2.2.0
82+
pytest==8.3.3
83+
```
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from geopy.distance import geodesic
2+
3+
4+
def calculate_distance_and_time(coord1, coord2, avg_speed):
5+
"""
6+
Calculate the distance between two coordinates and estimate travel time.
7+
:param coord1: Tuple containing the latitude and longitude of the first location (lat1, lon1)
8+
:param coord2: Tuple containing the latitude and longitude of the second location (lat2, lon2)
9+
:param avg_speed: Average speed in km/h for estimating travel time
10+
:return: Distance in kilometers and estimated travel time in hours
11+
"""
12+
13+
# Calculate geodesic distance
14+
distance = geodesic(coord1, coord2).kilometers
15+
# Estimate travel time (distance / speed)
16+
travel_time = distance / avg_speed
17+
18+
return distance, travel_time
19+
20+
21+
def main():
22+
# Coordinates (latitude, longitude)
23+
try:
24+
coord1 = tuple(map(float, input('Enter the latitude and longitude of the first location (lat1, lon1) Example: 40.7128, -74.006: ').split(',')))
25+
coord2 = tuple(map(float, input('Enter the latitude and longitude of the second location (lat2, lon2) Example: 37.7749, -122.4194: ').split(',')))
26+
except ValueError as e:
27+
raise ValueError("Coordinates must be in the format 'lat, lon'") from e
28+
29+
if not all(-90 <= x <= 90 for x in (coord1[0], coord2[0])) or not all(-180 <= x <= 180 for x in (coord1[1], coord2[1])):
30+
raise ValueError('Invalid coordinates')
31+
32+
# Speed in km/h (e.g., driving speed)
33+
try:
34+
avg_speed = float(input('Enter the average speed in km/h Example: 60: '))
35+
except ValueError as e:
36+
raise ValueError('Average speed must be a number') from e
37+
38+
if avg_speed <= 0:
39+
raise ValueError('Average speed must be greater than 0.')
40+
41+
# Calculate the distance and travel time
42+
distance, travel_time = calculate_distance_and_time(coord1, coord2, avg_speed)
43+
44+
print(f'Distance between the two coordinates: {distance:.2f} kilometers')
45+
print(f'Estimated travel time: {travel_time:.2f} hours')
46+
47+
48+
if __name__ == '__main__':
49+
main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
geopy==2.4.1
2+
pytest==8.3.3

Geographic Distance/runtime.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
python-3.12.7
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from unittest.mock import patch
2+
3+
import pytest
4+
from geographic_distance import calculate_distance_and_time, main
5+
6+
7+
def test_calculate_distance_and_time():
8+
# Test with valid coordinates and speed
9+
coord1 = (40.7128, -74.006)
10+
coord2 = (37.7749, -122.4194)
11+
avg_speed = 60
12+
distance, travel_time = calculate_distance_and_time(coord1, coord2, avg_speed)
13+
assert distance > 0
14+
assert travel_time > 0
15+
16+
17+
def test_calculate_distance_and_time_invalid_speed():
18+
# Test with invalid speed (zero)
19+
coord1 = (40.7128, -74.006)
20+
coord2 = (37.7749, -122.4194)
21+
avg_speed = 0
22+
with pytest.raises(ValueError):
23+
calculate_distance_and_time(coord1, coord2, avg_speed)
24+
25+
26+
def test_calculate_distance_and_time_same_coordinates():
27+
# Test with same coordinates
28+
coord1 = (40.7128, -74.006)
29+
coord2 = (40.7128, -74.006)
30+
avg_speed = 60
31+
distance, travel_time = calculate_distance_and_time(coord1, coord2, avg_speed)
32+
assert distance == 0
33+
assert travel_time == 0
34+
35+
36+
@pytest.fixture
37+
def mock_input():
38+
with patch('builtins.input', side_effect=['40.7128, -74.006', '37.7749, -122.4194', '60']):
39+
yield
40+
41+
42+
def test_main(mock_input, capsys):
43+
main()
44+
captured = capsys.readouterr()
45+
assert 'Distance between the two coordinates:' in captured.out
46+
assert 'Estimated travel time:' in captured.out
47+
48+
49+
def test_main_invalid_coordinates(mock_input, capsys):
50+
with patch('builtins.input', side_effect=['abc, def', '37.7749, -122.4194', '60']):
51+
with pytest.raises(ValueError):
52+
main()
53+
54+
55+
def test_main_invalid_speed(mock_input, capsys):
56+
with patch('builtins.input', side_effect=['40.7128, -74.006', '37.7749, -122.4194', 'abc']):
57+
with pytest.raises(ValueError):
58+
main()
59+
60+
61+
def test_main_zero_speed(mock_input, capsys):
62+
with patch('builtins.input', side_effect=['40.7128, -74.006', '37.7749, -122.4194', '0']):
63+
with pytest.raises(ValueError):
64+
main()
65+
66+
67+
def test_main_same_coordinates(mock_input, capsys):
68+
with patch('builtins.input', side_effect=['40.7128, -74.006', '40.7128, -74.006', '60']):
69+
main()
70+
captured = capsys.readouterr()
71+
assert 'Distance between the two coordinates: 0.00 kilometers' in captured.out
72+
assert 'Estimated travel time: 0.00 hours' in captured.out

0 commit comments

Comments
 (0)