Python dla nieinformatyków

Materiały dla studentów biologii i inżynierii mechanicznej

Python tu nie po to, żebyś został programistą. Po to, żeby:

  • biologia: wczytać wyniki pomiarów z pliku, policzyć średnie/odchylenia, wysunąć duplikaty, narysowac krzywe wzrostu,
  • mechanika: zautomatyzowac obliczenia, zrobić wykresy z danych pomiarowych, obliczyc serie pomiarów zamiast w Excelu z wzorkami.

Programowanie = dokładny przepis dla komputera. Komputer robi dokładnie to, co napiszesz, szybko i bez zmęczenia.


1. Instalacja

  1. Pobierz Pythona: https://python.org — przy instalacji zaznacz „Add Python to PATH".
  2. Sprawdź w terminalu (Windows: cmd lub PowerShell):
python --version
  1. Do analizy danych instalujesz gotowe biblioteki:
pip install pandas matplotlib

pip to magazyn gotowych pakietów. Zamiast pisać analizę od zera, pobierasz sprawdzoną już.


2. Pierwszy skrypt

Utwórz plik analiza.py w dowolnym edytorze (Notatnik też zadziała, ale zalecam VS Code — darmowy) i uruchom:

python analiza.py

Prosty przykład — analiza temperatur w inkubatorze:

temperatury = [36.8, 36.9, 37.0, 37.1, 36.9, 37.0, 37.2, 36.9]

średnia = sum(temperatury) / len(temperatury)
print(f"Temperatura śr.: {średnia:.2f} °C")
print(f"Min: {min(temperatury):.2f} °C, Max: {max(temperatury):.2f} °C")

Wynik:

Temperatura śr.: 36.99 °C
Min: 36.80 °C, Max: 37.20 °C

Kolejność: 1. temperatury = [...] — zapamiętujesz listę wartości (zawsze od zera licząc!). 2. sum() / len() — gotowe funkcje: suma i długość listy. 3. print(...) — wyświetla wynik na ekranie. 4. f"..." — łańcuch z wbudowanymi zmiennymi; :.2f to „dwie cyfry po przecinku".


3. Zmienne i typy

Zmienna = nazwa przypisana do wartości.

masa_komorki_1 = 0.042     # float (wagi, temperatury)
masa_komorki_2 = 0.043     # nie musisz deklarować typu
liczba_zawartości = 10     # int — liczba naturalna
nazwa_bakterii = "E. coli"  # str — łańcuch znaków

Typы:

Typ Kiedy Przykład
int dyskretna wartość 3 — liczba pomiarów
float wielkości ciągłe 0.042 — masa, siła
str tekst "E. coli" — nazwa próbki
bool prawda/fałsz True — warunek spełniony
list kolekcja o sekwencji [36.8, 37.0] — pomiary
dict mapa klucz → wartość {"próba 1": 0.042}

f-strings — podstawowy sposób „mówienia" z kodem

siła = 450
masa = 2.3
print(f"Siła: {siła} N")           # Siła: 450 N
print(f"Przyspieszenie: {siła/masa:.1f} m/s²")  # Przyspieszenie: 196 m/s²

.1f = jedna cyfra po przecinku, .2f = dwie. Bardzo praktyczne przy raportach pomiarowych.


4. Warunki

# Biologia: stężenie antybiotyku
stężenie = 12.5   # µg/mL

if stężenie < 10:
    print("Stężenie subinhibycyjne")
elif stężenie < 50:
    print("Stężenie terapeutyczne")
else:
    print("Stężenie bakteriobójcze")
# Mechanika: granice wytrzymałości
naprężenie = 320   # MPa
wytrzymalosc = 360  # MPa

bezpieczny = naprężenie < wytrzymalosc * 0.8
if bezpieczny:
    print("Element w normie")
else:
    print("Przekroczenie dopuszczalnej granicy")
  • and, or, not — logiczne (działają jak w Excelu, tylko nazwy).
  • == porównuje, = przypisuje. Najczęstszy błąd na starcie.

5. Pętle

for — powtarza blok kodu po każdym elemencencie kolekcji:

# Obliczanie przyspieszenia dla serii mas
masy = [1.0, 2.0, 3.0, 5.0]     # kg
siła = 10                       # N

for m in masy:
    a = siła / m
    print(f"m = {m} kg → a = {a:.2f} m/s²")
# Biologia: przeliczanie stężeń
rozcieżenie = 100   # µg/mL, rozcieżenie macierzyste

for rozcieżenie in range(1, 6):
    stężenie = rozcieżenie * 10
    print(f"Rozcieżenie 1:{rozcieżenie * 10} → {stężenie} µg/mL")

range(1, 6) to sekwencja 1, 2, 3, 4, 5 (ostatni exclusive).

while — powtarzaj, póki warunek prawdziwy

# Podwajanie dobowej dawki
dobowa_dawka = 250   # mg
cel = 2000           # mg
dni = 0

while dobowa_dawka < cel:
    dobowa_dawka *= 2
    dni += 1

print(f"Osiągnięto {dobowa_dawka} mg po {dni} dniach (dwu­stronnie)")

break i continue

# break: zatrzymuje całą pętlę
# continue: pomija tę iterację, idzie do następnej

for pomiar in [36.9, 37.1, 99.9, 37.0]:
    if pomiar > 50:
        print(f"Odcięcie: {pomiar} — błąd pomiaru")
        continue    # pomijamy tę wartość, idziemy dalej
    print(f"OK: {pomiar} °C")

6. Funkcje

Funkcja = nazwany przepis. Pisziesz raz, używasz wielokrotnie.

def średnia_odchylenie(temperatury):
    """Zwraca (średnią, odchylenie std) listy temperatur."""
    n = len(temperatury)
    śr = sum(temperatury) / n
    odchylenie = (sum((x - śr) ** 2 for x in temperatury) / (n - 1)) ** 0.5
    return śr, odchylenie

# Użycie
temperatury = [36.8, 36.9, 37.0, 37.1, 36.9, 37.0, 37.2, 36.9]
śr, odch = średnia_odchylenie(temperatury)
print(f"Śr. = {śr:.2f} °C (±{odch:.2f})")

Zwracania wielu wartościc — Python „rozpakowuje" je w osobne zmienne.

# Parametry domyślne — wygodne dla często używanych funkcji
def przyspieszenie(silę_N, masa_kg=1.0):
    """Zwraca przyspieszenie w m/s²."""
    return silę_N / masa_kg

przyspieszenie(10)           # 10.0  (masa = 1.0 domyślnie)
przyspieszenie(10, masa_kg=2.5)  # 4.0
# Funkcja z pętlą w środku
def polinom_sterowania(wartosci, granica):
    """Liczy jak wiele wartości przekroczyło granicę."""
    przekroczone = [x for x in wartosci if x > granica]
    return len(przekroczonych)

przekroczenia = polinom_sterowania([320, 340, 380, 310], 360)
print(f"Przekroczenia: {przekroczenia} / 4")

Dobre zasady: - Nazwa czasownikowa: oblicz_przyspieszenie, wczytaj_dane, znajdz_wykreślone. - Jedna funkcja = jedna odpowiedzialność. - Dostaw dok­umentację (docstring) pod nazwą.


7. Pliki — czytanie danych pomiarowych

# Zapis do pliku
with open("wyniki_eksperymentu.txt", "w", encoding="utf-8") as f:
    f.write("Dzień 1 pomiarów\n")
    f.write(f"Temperatura: {36.9} °C\n")
    f.write(f"Czas: 2.5 h\n")

# Odczyt
with open("wyniki_eksperymentu.txt", "r", encoding="utf-8") as f:
    calosc = f.read()
    print(calość)

with gwarantuje zamknięcie pliku po zakończeniu. To standard.

Format CSV — najpopularniejszy format danych

Pomiar z aparatu eksportowany do .csv:

dzień,temperatura_srednia,liczba_komorek
1,36.9,1.2e6
2,37.0,2.8e6
3,37.1,6.5e6
4,37.0,1.3e7
# Czytanie CSV bez bibliotek (przydatne do zrozumienia)
linii = []
with open("wzrost_bakterii.csv", "r", encoding="utf-8") as f:
    naglowek = f.readline().strip().split(",")
    for linia in f:
        wartosci = linia.strip().split(",")
        pomiar = dict(zip(naglowek, wartosci))
        linii.append(pomiar)
        print(f"Dzień {pomiar['dzień']}: {float(pomiar['liczba_komorek']):.2e} komórek")

zip() paruje nagłówki z wartościami. dict() tworzy mapę {kolumna: wartość}.


8. Pandas — biblioteka do tabel

Pandas to „Excel w Pythonie" — struktura o nazwie DataFrame (tablica o kolumnach).

Instalacja + import

pip install pandas
import pandas as pd

# Odczyt CSV
wzrost = pd.read_csv("wzrost_bakterii.csv")
print(wzrost)
print(f"\nWymiary: {wzrost.shape} wierszy, {len(wzrost.columns)} kolumn")
print(f"\nKolumny: {list(wzrost.columns)}")

Podstawowe operacje

# Podgląd i statystyki
wzrost.head()         # pierwsze 5 wierszy
wzrost.describe()     # statystyki opisowe — auto!

# Filtr — tylko dni z temperaturą > 36.95
gorące = wzrost[wzrost["temperatura_srednia"] > 36.95]
print(gorące)

# Sortowanie
posortowane = wzrost.sort_values("liczba_komorek", ascending=False)
print(posortowane.head())

# Nowa kolumna — przeliczenie
wzrost["stężenie_mg_L"] = wzrost["liczba_komorekc"] * 0.020

# Agregacje
wzrost["liczba_komorekc"].mean()   # średnia
wzrost["liczba_komorekc"].sum()    # suma
wzrost["liczba_komorekc"].max()    # maksimum

# Grupa (np. dzielnio do grup eksperymentalnych)
grupa_A = wzrost[wzrost["eksperyment"].isin(["A1", "A2"])]
print(f"Śr. A: {grupa_A['liczba_komorekc'].mean():.2e}")

Eksport

# Zapis do CSV (bez nagłówka: index=False)
wzrost.to_csv("po_eksportsie.csv", index=False)

# Zapis do Excela (wymaga: pip install openpyxl)
wzrost.to_excel(
    "po_eksportsie.xlsx",
    sheet_name="Dane pomiarowe",
    index=False,
)

9. Matplotlib — rysowanie wykresów

import matplotlib.pyplot as plt

# Przykład: krzywa wzrostu bakterii
wzrost = pd.read_csv("wzrost_bakterii.csv")

plt.figure(figsize=(9, 5))
plt.plot(
    wzrost["dzień"],
    wzrost["liczba_komorekc"],
    "o-                    # kółka + linia
)

plt.title("Wzrost populacji E. coli")
plt.xlabel("Dzień hodowli")
plt.ylabel("Liczba komórek")
plt.grid(True, alpha=0.3)   # siatka
plt.tight_layout()
plt.savefig("krzywa_wzrostu.png", dpi=150)  # zapis do pliku
plt.show()

Wykres słupkowy (porównanie próbek)

# Mechanika: granice wytrzymałości materiałów
materiały = ["ST37", "20MnCr5", "X20Cr13", "AlMg1"]
wytrzymałość = [235, 570, 515, 260]   # MPa

colors = ["lightblue", "steelblue", "darkblue", "slateblue"]

bars = plt.bar(materiały, wytrzymałość, color=colors)
plt.title("Przepustowość rozciągania — porównanie")
plt.xlabel("Materiał")
plt.ylabel("Wytrzymałość [MPa]")
for i, bar in enumerate(bars):
    plt.text(bar.get_x() + bar.get_width() / 2, bar.get_height(),
             f"{bar.get_height():.0f}",
             ha='center', va='bottom', fontsize=10)
plt.tight_layout()

Wykres logarytmiczny (biologia — wzrosty)

# Logarytmiczna krzywa wzrostu — bardzo typowa dla kinetyki
import numpy as np
t = np.linspace(0, 20, 100)
N = 1e6 * np.exp(0.3 * t)   # model wzrostu wykładniczego

plt.figure()
plt.plot(t, N, 'o-', color='darkgreen')
plt.yscale_log()            # oś Y logarytmiczna
plt.title("Wzrost komórek (oś log) — pełne stadium")
plt.xlabel("Czas [h]")
plt.ylabel("Populacja (komórki)")
plt.grid(True, alpha=0.3, which='both')

Jeśli wzrost jest wykładniczy, skala logarytmiczna zamienia go w linię prostą — dużo czytelniejsza.

Podmny wykresy (subplot)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

ax1.plot([0, 5, 10, 15, 20], [10, 50, 120, 200, 260], 'o-')
ax1.set_title("Wzrost")
ax1.set_xlabel("Czas [h]")

ax2.bar(["Próbka A", "Próbka B", "Próbka C"], [45, 62, 38], color='steelblue')
ax2.set_title("Porównanie")

plt.tight_layout()

10. Najczęstsze błędy i ich naprawa

Błąd Co robić
NameError: name 'x' is not defined Literówka albo zmienna nie istnieje — szukaj
IndentationError Wcięcia — używaj SPACJI, nie TABÓW
ZeroDivisionError Dzielenie przez zero — sprawdź wartość mianownika
FileNotFoundError Sprawdź ścieżkę; używaj pełnej ścieżki /Users/...
KeyError: 'kolumna' Nazwa kolumny w DataFrame — sprawdź wzrost.columns
ImportError Zła kolejność importów; sprawdź pip install

Debugowanie — drukowanie pośrednich wartości

# Zamiast zgadywać, drukuj wartości krok po kroku
for i, pomiar in enumerate(pomiary):
    print(f"[{i}] surowy: {pomiar}")
    if pomiar > 1000:
        print(f"[{i}] PO przekroczeniu granicy!")
    print(f"[{i}] po filtrowaniu: {filtrowanie(pomiar)}")

Wskazówka: czytaj komunikaty błędów od końca

Traceback (most recent call last):
  File "analiza.py", line 5, in <module>
    wynik = wartość / masa
  File "...", line 1, in <module>
ZeroDivisionError: division by zero

Ostatnia linia = prawdziwy błąd. Górne wiersze = gdzie to się stało.


11. Gdzie dalej?

Biologia:

  • Biopython (https://biopython.org/) — sekwencje DNA, struktury białek
  • scikit-learn — klasyfikacja, clustering (k-means dla grup komórkowych)
  • Seaborn — ładniejsze wykresy statystyczne (jeden wiersz)

Inżynieria:

  • SciPy — numeryka: całkowanie, interpolacja, transformacje
  • PyQt — interfejsy graficzne dla aplikacji pomiarowych
  • NumPy — tablice 3D, operacje macierzowe

Ogólnie:

  • Python Data Science Handbook (Weinberg) — standard
  • Real Python (https://realpython.com/) — porządne artykuły
  • GeeksforGeeks / Stack Overflow — odpowiedzi praktyczne

Najważniejsza rada: nie ucz się syntaksy, ucz się myślenia o problemach. Każde zadanie rozpisz na papierze, zanim zaczniesz kodować.