Obliczanie prędkości ucieczki w Pythonie
Wyobraź sobie, że rzucasz piłkę w górę. Zawsze spada z powrotem, prawda? A co, gdybyś rzucił ją tak mocno, że nigdy by nie wróciła? To właśnie jest prędkość ucieczki - minimalna prędkość potrzebna do wyrwania się z grawitacji planety. Dziś napiszemy program, który obliczy tę prędkość dla dowolnego ciała niebieskiego używając NumPy - potężnej biblioteki Pythona do obliczeń naukowych.
Dlaczego NumPy zamiast zwykłego Pythona?
Choć wbudowane funkcje matematyczne Pythona działają dobrze dla prostych obliczeń, NumPy oferuje kilka zalet dla obliczeń naukowych:
- Większa wydajność dla obliczeń na dużą skalę
- Lepsza stabilność numeryczna i kontrola precyzji
- Operacje wektorowe - obliczanie dla wielu planet jednocześnie
- Standard branżowy dla naukowego Pythona
Najpierw zainstalujmy NumPy (jeśli jeszcze nie masz):
pip install numpy
Zrozumienie problemu
Zanim zaczniemy kodować, zastanówmy się, co właściwie musimy zrobić:
- Znamy wzór fizyczny: v = √(2GM/r)
- Potrzebujemy danych wejściowych: masa planety i jej promień
- Musimy wykonać obliczenia matematyczne
- Wyświetlimy wynik w czytelnej formie
Brzmi prosto? Bo tak właśnie jest. Ale najpierw musimy zrozumieć jeden ważny koncept używany w obliczeniach astronomicznych.
Notacja naukowa - sposób na ogromne liczby
Masa Ziemi to około 5 972 000 000 000 000 000 000 000 kilogramów. Niewygodne do zapisania, prawda? Dlatego w nauce używamy notacji naukowej:
5.972 × 10²⁴ kg
W Pythonie zapisujemy to jako 5.972e24, gdzie:
5.972to mantysa (główna liczba)eoznacza "razy 10 do potęgi"24to wykładnik (o ile miejsc przesuwamy przecinek)
Kilka przykładów z NumPy:
import numpy as np
# Notacja naukowa w NumPy
earth_mass = np.float64(5.972e24) # 5.972 × 10²⁴
earth_radius = np.float64(6.371e6) # 6.371 × 10⁶ (6 371 000 metrów)
gravity_constant = np.float64(6.674e-11) # 6.674 × 10⁻¹¹ (bardzo mała liczba)
# NumPy efektywnie obsługuje te liczby
print(f"Masa Ziemi: {earth_mass}") # Wyświetli: 5.972e+24
print(f"To jest: {earth_mass:,.0f}") # Wyświetli z wszystkimi zerami
Uwaga: Wyświetlona liczba może nie pokazywać dokładnych zer na końcu ze względu na precyzję zmiennoprzecinkową, ale float64 NumPy zapewnia doskonałą dokładność dla naszych obliczeń.
Rozbijamy problem na kroki
Teraz, gdy rozumiemy notację, rozpiszmy nasze rozwiązanie krok po kroku:
Krok 1: Zdefiniuj stałe i dane
Najpierw określmy, co wiemy:
import numpy as np
# Stała grawitacyjna - zawsze taka sama we wszechświecie
G = np.float64(6.67430e-11) # m³ kg⁻¹ s⁻²
# Dane dla Ziemi (jako przykład)
earth_mass = np.float64(5.972e24) # kilogramy
earth_radius = np.float64(6.371e6) # metry (6371 km)
Krok 2: Zastosuj wzór
Teraz podstawmy do wzoru v = √(2GM/r):
# Obliczenie krok po kroku
numerator = 2 * G * earth_mass
denominator = earth_radius
division_result = numerator / denominator
escape_velocity = np.sqrt(division_result)
print(f"Prędkość ucieczki: {escape_velocity:.0f} m/s")
Krok 3: Uprość kod
Gdy już rozumiemy każdy krok, możemy zapisać to krócej:
import numpy as np
G = np.float64(6.67430e-11)
earth_mass = np.float64(5.972e24)
earth_radius = np.float64(6.371e6)
escape_velocity = np.sqrt(2 * G * earth_mass / earth_radius)
print(f"Prędkość ucieczki z Ziemi: {escape_velocity/1000:.1f} km/s")
Wersja 1: Funkcja do wielokrotnego użytku
Zamiast kopiować kod dla każdej planety, stwórzmy funkcję:
import numpy as np
def calculate_escape_velocity(mass, radius):
"""
Oblicza prędkość ucieczki dla dowolnego ciała niebieskiego.
Parametry:
mass: masa w kilogramach
radius: promień w metrach
Zwraca:
prędkość ucieczki w m/s
"""
G = np.float64(6.67430e-11)
return np.sqrt(2 * G * mass / radius)
# Testujemy dla różnych planet
print("PRĘDKOŚCI UCIECZKI W UKŁADZIE SŁONECZNYM")
print("-" * 40)
# Ziemia
v = calculate_escape_velocity(5.972e24, 6.371e6)
print(f"Ziemia: {v/1000:.1f} km/s")
# Mars
v = calculate_escape_velocity(6.417e23, 3.3895e6)
print(f"Mars: {v/1000:.1f} km/s")
# Księżyc
v = calculate_escape_velocity(7.342e22, 1.7374e6)
print(f"Księżyc: {v/1000:.1f} km/s")
Wersja 2: Program z bazą planet
Teraz stwórzmy bardziej użyteczny program z gotową bazą danych. NumPy naprawdę błyszczy tutaj z operacjami wektorowymi:
import numpy as np
# Słownik z danymi planet
planets = {
"Merkury": {"mass": 3.301e23, "radius": 2.4397e6},
"Wenus": {"mass": 4.867e24, "radius": 6.0518e6},
"Ziemia": {"mass": 5.972e24, "radius": 6.371e6},
"Mars": {"mass": 6.417e23, "radius": 3.3895e6},
"Jowisz": {"mass": 1.898e27, "radius": 6.9911e7},
"Saturn": {"mass": 5.683e26, "radius": 5.8232e7},
"Uran": {"mass": 8.681e25, "radius": 2.5362e7},
"Neptun": {"mass": 1.024e26, "radius": 2.4622e7},
"Księżyc": {"mass": 7.342e22, "radius": 1.7374e6}
}
def calculate_escape_velocity(mass, radius):
G = np.float64(6.67430e-11)
return np.sqrt(2 * G * mass / radius)
def show_planet_data(name, data):
"""Wyświetla dane planety i jej prędkość ucieczki."""
v_escape = calculate_escape_velocity(data["mass"], data["radius"])
print(f"\n{name}:")
print(f" Masa: {data['mass']:.2e} kg")
print(f" Promień: {data['radius']/1000:.0f} km")
print(f" Prędkość ucieczki: {v_escape:.0f} m/s ({v_escape/1000:.1f} km/s)")
# Wyświetlamy dane dla wszystkich planet
print("="*50)
print("PRĘDKOŚCI UCIECZKI W UKŁADZIE SŁONECZNYM")
print("="*50)
for planet_name, planet_data in planets.items():
show_planet_data(planet_name, planet_data)
# Bonus: Oblicz wszystko naraz używając tablic NumPy!
print("\n" + "="*50)
print("OBLICZENIA WEKTOROWE Z NUMPY")
print("="*50)
names = list(planets.keys())
masses = np.array([planets[p]["mass"] for p in names])
radii = np.array([planets[p]["radius"] for p in names])
# Oblicz wszystkie prędkości ucieczki naraz
G = np.float64(6.67430e-11)
all_velocities = np.sqrt(2 * G * masses / radii)
for i, name in enumerate(names):
print(f"{name}: {all_velocities[i]/1000:.1f} km/s")
Wersja 3: Interaktywny kalkulator
Teraz najciekawsza część - program, który pozwala użytkownikom wybierać planety lub wprowadzać własne dane:
import numpy as np
# Baza danych planet
planets_db = {
"1": {"name": "Merkury", "mass": 3.301e23, "radius": 2.4397e6},
"2": {"name": "Wenus", "mass": 4.867e24, "radius": 6.0518e6},
"3": {"name": "Ziemia", "mass": 5.972e24, "radius": 6.371e6},
"4": {"name": "Mars", "mass": 6.417e23, "radius": 3.3895e6},
"5": {"name": "Jowisz", "mass": 1.898e27, "radius": 6.9911e7},
"6": {"name": "Saturn", "mass": 5.683e26, "radius": 5.8232e7},
"7": {"name": "Uran", "mass": 8.681e25, "radius": 2.5362e7},
"8": {"name": "Neptun", "mass": 1.024e26, "radius": 2.4622e7},
"9": {"name": "Księżyc", "mass": 7.342e22, "radius": 1.7374e6}
}
def calculate_escape_velocity(mass, radius):
"""Oblicza prędkość ucieczki używając NumPy."""
G = np.float64(6.67430e-11)
mass = np.float64(mass)
radius = np.float64(radius)
return np.sqrt(2 * G * mass / radius)
def display_menu():
"""Wyświetla menu wyboru."""
print("\n" + "="*50)
print("KALKULATOR PRĘDKOŚCI UCIECZKI (Edycja NumPy)")
print("="*50)
print("\nWybierz planetę:")
for key, planet in planets_db.items():
print(f" {key}. {planet['name']}")
print("\n 10. Wprowadź własne parametry")
print(" 0. Wyjście")
print("-"*50)
def get_custom_parameters():
"""Pobiera parametry od użytkownika."""
print("\nWPROWADŹ DANE CIAŁA NIEBIESKIEGO")
name = input("Nazwa: ")
while True:
try:
mass_str = input("Masa w kg (np. 5.972e24): ")
mass = float(mass_str)
if mass <= 0:
print("Masa musi być dodatnia!")
continue
break
except ValueError:
print("Nieprawidłowa wartość! Spróbuj ponownie.")
while True:
try:
radius_str = input("Promień w km: ")
radius = float(radius_str) * 1000 # konwersja na metry
if radius <= 0:
print("Promień musi być dodatni!")
continue
break
except ValueError:
print("Nieprawidłowa wartość! Spróbuj ponownie.")
return name, mass, radius
def display_results(name, mass, radius):
"""Wyświetla wyniki obliczeń."""
v_escape = calculate_escape_velocity(mass, radius)
print(f"\n{'='*50}")
print(f"WYNIKI DLA: {name}")
print(f"{'='*50}")
print(f"Masa: {mass:.2e} kg")
print(f"Promień: {radius/1000:,.0f} km")
print(f"\nPrędkość ucieczki:")
# Lepsze obsługiwanie bardzo małych wartości
if v_escape < 0.01:
print(f" → {v_escape:.2e} m/s")
else:
print(f" → {v_escape:,.0f} m/s")
print(f" → {v_escape/1000:.2f} km/s")
# Porównanie z Ziemią
earth_v = calculate_escape_velocity(5.972e24, 6.371e6)
if name.lower() != "ziemia":
ratio = v_escape / earth_v
print(f"\nPorównanie z Ziemią: {ratio:.2f}x")
def main():
"""Główna pętla programu."""
print("Witaj w kalkulatorze prędkości ucieczki!")
print("Napędzany przez NumPy dla dokładnych obliczeń naukowych")
while True:
display_menu()
choice = input("\nTwój wybór: ")
if choice == "0":
print("\nDo zobaczenia! ?")
break
elif choice in planets_db:
planet = planets_db[choice]
display_results(planet["name"], planet["mass"], planet["radius"])
elif choice == "10":
name, mass, radius = get_custom_parameters()
display_results(name, mass, radius)
else:
print("\nNieprawidłowy wybór!")
input("\nNaciśnij Enter aby kontynuować...")
# Uruchomienie programu
if __name__ == "__main__":
main()
Przykład użycia dla nieznanej planety
Załóżmy, że odkryto nową egzoplanetę. Możesz użyć opcji "własne parametry" i wprowadzić:
- Nazwa: Kepler-452b
- Masa: 3.0e25 kg (5 razy masa Ziemi)
- Promień: 9556 km (1.5 raza promień Ziemi)
Program obliczy prędkość ucieczki i porówna ją z Ziemią. To świetny sposób na eksplorowanie hipotetycznych scenariuszy!
Moc NumPy: Obliczenia wsadowe
Jedną z supermocy NumPy jest obliczanie dla wielu obiektów naraz:
import numpy as np
# Oblicz prędkości ucieczki dla wielu ciał naraz
names = np.array(['Mała Asteroida', 'Duża Asteroida', 'Rozmiar Księżyca'])
masses = np.array([1e15, 1e18, 1e22]) # kg
radii = np.array([10000, 100000, 1000000]) # metry
G = np.float64(6.67430e-11)
velocities = np.sqrt(2 * G * masses / radii)
print("Wyniki obliczeń wsadowych:")
for i in range(len(names)):
print(f"{names[i]}: {velocities[i]:.2f} m/s")
Co dalej?
Teraz, gdy masz działający kalkulator z NumPy, możesz go rozbudować:
- Dodaj więcej obiektów: asteroidy, komety, gwiazdy
- Oblicz prędkość orbitalną: to prędkość ucieczki podzielona przez √2
- Przetwarzaj pliki CSV: wczytuj dane planet z plików używając NumPy
- Twórz wizualizacje: wykreśl prędkości ucieczki z matplotlib
- Symuluj trajektorie: użyj tablic NumPy do mechaniki orbitalnej
Podsumowanie
Przeszliśmy od prostego wzoru do pełnoprawnego kalkulatora używającego NumPy. Po drodze nauczyłeś się:
- Dlaczego NumPy jest preferowany do obliczeń naukowych
- Jak używać notacji naukowej w Pythonie
- Jak tworzyć funkcje wielokrotnego użytku
- Jak wykonywać obliczenia wektorowe na wielu obiektach
- Jak budować interaktywne programy naukowe
Pamiętaj - NumPy to fundament naukowego Pythona. Opanuj go, a będziesz gotowy na bardziej zaawansowane biblioteki jak SciPy, Pandas i Matplotlib.
Powodzenia w obliczaniu prędkości ucieczki z różnych światów!
import numpy as np
# Baza danych planet
planets_db = {
"1": {"name": "Merkury", "mass": 3.301e23, "radius": 2.4397e6},
"2": {"name": "Wenus", "mass": 4.867e24, "radius": 6.0518e6},
"3": {"name": "Ziemia", "mass": 5.972e24, "radius": 6.371e6},
"4": {"name": "Mars", "mass": 6.417e23, "radius": 3.3895e6},
"5": {"name": "Jowisz", "mass": 1.898e27, "radius": 6.9911e7},
"6": {"name": "Saturn", "mass": 5.683e26, "radius": 5.8232e7},
"7": {"name": "Uran", "mass": 8.681e25, "radius": 2.5362e7},
"8": {"name": "Neptun", "mass": 1.024e26, "radius": 2.4622e7},
"9": {"name": "Księżyc", "mass": 7.342e22, "radius": 1.7374e6}
}
def calculate_escape_velocity(mass, radius):
"""Oblicza prędkość ucieczki używając NumPy."""
G = np.float64(6.67430e-11)
mass = np.float64(mass)
radius = np.float64(radius)
return np.sqrt(2 * G * mass / radius)
def display_menu():
"""Wyświetla menu wyboru."""
print("\n" + "="*50)
print("KALKULATOR PRĘDKOŚCI UCIECZKI (Edycja NumPy)")
print("="*50)
print("\nWybierz planetę:")
for key, planet in planets_db.items():
print(f" {key}. {planet['name']}")
print("\n 10. Wprowadź własne parametry")
print(" 0. Wyjście")
print("-"*50)
def get_custom_parameters():
"""Pobiera parametry od użytkownika."""
print("\nWPROWADŹ DANE CIAŁA NIEBIESKIEGO")
name = input("Nazwa: ")
while True:
try:
mass_str = input("Masa w kg (np. 5.972e24): ")
mass = float(mass_str)
if mass <= 0:
print("Masa musi być dodatnia!")
continue
break
except ValueError:
print("Nieprawidłowa wartość! Spróbuj ponownie.")
while True:
try:
radius_str = input("Promień w km: ")
radius = float(radius_str) * 1000 # konwersja na metry
if radius <= 0:
print("Promień musi być dodatni!")
continue
break
except ValueError:
print("Nieprawidłowa wartość! Spróbuj ponownie.")
return name, mass, radius
def display_results(name, mass, radius):
"""Wyświetla wyniki obliczeń."""
v_escape = calculate_escape_velocity(mass, radius)
print(f"\n{'='*50}")
print(f"WYNIKI DLA: {name}")
print(f"{'='*50}")
print(f"Masa: {mass:.2e} kg")
print(f"Promień: {radius/1000:,.0f} km")
print(f"\nPrędkość ucieczki:")
# Lepsze obsługiwanie bardzo małych wartości
if v_escape < 0.01:
print(f" → {v_escape:.2e} m/s")
else:
print(f" → {v_escape:,.0f} m/s")
print(f" → {v_escape/1000:.2f} km/s")
# Porównanie z Ziemią
earth_v = calculate_escape_velocity(5.972e24, 6.371e6)
if name.lower() != "ziemia":
ratio = v_escape / earth_v
print(f"\nPorównanie z Ziemią: {ratio:.2f}x")
def main():
"""Główna pętla programu."""
print("Witaj w kalkulatorze prędkości ucieczki!")
print("Napędzany przez NumPy dla dokładnych obliczeń naukowych")
while True:
display_menu()
choice = input("\nTwój wybór: ")
if choice == "0":
print("\nDo zobaczenia! ?")
break
elif choice in planets_db:
planet = planets_db[choice]
display_results(planet["name"], planet["mass"], planet["radius"])
elif choice == "10":
name, mass, radius = get_custom_parameters()
display_results(name, mass, radius)
else:
print("\nNieprawidłowy wybór!")
input("\nNaciśnij Enter aby kontynuować...")
# Uruchomienie programu
if __name__ == "__main__":
main()