Managing Astronaut Medical Data with Python - Embark on an interstellar coding mission to create a Cosmic Health Tracker using Python. This beginner-friendly guide will teach you how to manage astronaut medical data with a graphical interface, database operations, and error handling.

Managing Astronaut Medical Data with Python

Strap in, future space programmer! Today, we're going to build a Cosmic Health Tracker - a Python program that manages astronaut medical data on a space station. By the end of this mission, you'll have created a fully functional program with a graphical interface, perfect for keeping our space explorers in tip-top shape!

Note: You can find the complete code for this project in the "Article's code" tab above the content of this article. Feel free to peek ahead if you're curious, but we recommend following along step-by-step for the best learning experience!

1. Setting Up Our Python Environment

Before we blast off, let's make sure we have all the necessary equipment. For this mission, we'll need:

  • Python 3.x installed on your computer
  • SQLite (comes pre-installed with Python)
  • Tkinter (usually comes with Python, but you might need to install it separately)
  • Create a new Python file called cosmic_health_tracker.py. This will be our mission control center!

2. Designing Our Astronaut Database

Every good space mission needs a solid foundation. In our case, that's our database. We'll use SQLite to create two tables:

  1. astronauts: To store personal information
  2. medical_records: To keep track of medical check-ups

Let's write some Python code to set up our database and main class, and then instantiate that class:

import sqlite3

class CosmicHealthTracker:

    def __init__(self):

        #let's create database first
        self.create_database()
        
    def create_database(self):
        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()

        cursor.execute('''
        CREATE TABLE IF NOT EXISTS astronauts (
            id INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            age INTEGER,
            nationality TEXT
        )
        ''')

        cursor.execute('''
        CREATE TABLE IF NOT EXISTS medical_records (
            id INTEGER PRIMARY KEY,
            astronaut_id INTEGER,
            check_up_date TEXT,
            heart_rate INTEGER,
            blood_pressure TEXT,
            weight REAL,
            FOREIGN KEY (astronaut_id) REFERENCES astronauts (id)
        )
        ''')

        conn.commit()
        conn.close()
        
# Instantiate the class
if __name__ == "__main__":
    CosmicHealthTracker() 
		

This code creates our database and tables if they don't already exist. It's like building the living quarters and medical bay of our space station.

3. Launching the Graphical User Interface

Now that we have our database, let's create a user-friendly interface for our space medical officers. We'll use Tkinter, Python's standard GUI library, to create windows, buttons, and entry fields.

# we're changing our import section
import sqlite3
import tkinter as tk
from tkinter import ttk

Our CosmicHealthTracker now needs master in its init section and some Tkinter GUI setup with basic functions that we'll implement later. Pass lets you create empty function, so you can run your code without implementing it at this point.

import sqlite3
import tkinter as tk
from tkinter import ttk

class CosmicHealthTracker:
    def __init__(self, master):
        self.master = master
        master.title("Cosmic Health Tracker") #title for our window
        master.geometry("600x400") # size of our Health Tracker

        self.notebook = ttk.Notebook(master)
        self.notebook.pack(expand=True, fill='both')

        self.astronaut_frame = ttk.Frame(self.notebook)
        self.medical_frame = ttk.Frame(self.notebook)

        self.notebook.add(self.astronaut_frame, text='Astronaut Info')
        self.notebook.add(self.medical_frame, text='Medical Records')

        self.create_database()        
        self.load_astronauts()        
        self.setup_astronaut_tab()
        self.setup_medical_tab()        

    def create_database(self):
        # Function already done so just copy it here

    def setup_astronaut_tab(self):
        pass # We'll add astronaut info fields here    

    def load_astronauts(self):        
        pass # We'll reload astronauts list here

    def view_astronauts(self):
        pass # We'll view a list of astronauts list here

    def setup_medical_tab(self):
        pass # We'll add medical record fields here

    def view_medical_records(self):
        pass # We'll view a list of medical records list here

root = tk.Tk()
app = CosmicHealthTracker(root)
root.mainloop()

This code sets up the basic structure of our GUI. It's like designing the control panels of our space station!

4. Astronaut Personal Data

Let's add some fields to input astronaut information. We're implementing setup_astronaut_tab and add_astronaut:

    def setup_astronaut_tab(self):
        #our name field
        ttk.Label(self.astronaut_frame, text="Name:").grid(row=0, column=0, padx=5, pady=5)
        self.name_entry = ttk.Entry(self.astronaut_frame)
        self.name_entry.grid(row=0, column=1, padx=5, pady=5)

        #our age field
        ttk.Label(self.astronaut_frame, text="Age:").grid(row=1, column=0, padx=5, pady=5)
        self.age_entry = ttk.Entry(self.astronaut_frame)
        self.age_entry.grid(row=1, column=1, padx=5, pady=5)

        #our nationality field
        ttk.Label(self.astronaut_frame, text="Nationality:").grid(row=2, column=0, padx=5, pady=5)
        self.nationality_entry = ttk.Entry(self.astronaut_frame)
        self.nationality_entry.grid(row=2, column=1, padx=5, pady=5)

        # botton to add data from the fields
        ttk.Button(self.astronaut_frame, text="Add Astronaut", command=self.add_astronaut).grid(row=3, column=0, columnspan=2, pady=10)

    def add_astronaut(self):
        name = self.name_entry.get()
        age = self.age_entry.get()
        nationality = self.nationality_entry.get()

        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()
        cursor.execute("INSERT INTO astronauts (name, age, nationality) VALUES (?, ?, ?)", (name, age, nationality))
        conn.commit()
        conn.close()

        # Clear the entry fields
        self.name_entry.delete(0, tk.END)
        self.age_entry.delete(0, tk.END)
        self.nationality_entry.delete(0, tk.END)    
        self.load_astronauts()  # Reload astronauts after adding a new one

This code allows us to input and save astronaut information. It's like registering new crew members for our space mission!

Python - space health monitor interface

5. Medical Check-ups

Now, let's add fields for medical check-ups. We need to:

  • display a form using setup_medical_tab with list of astronauts (load_astronauts),
  • and implement data adding function add_medical_record.
  • For now we also need to implement empty view_medical_records function.
  • In our impor section add from tkinter import messagebox. It will allow displaying messages about our successes and errors.
import sqlite3
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox #new import

Our new functions:

    def load_astronauts(self):
        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()
        cursor.execute("SELECT id, name FROM astronauts")
        self.astronauts = cursor.fetchall()
        conn.close()
        
    def setup_medical_tab(self):
        ttk.Label(self.medical_frame, text="Astronaut:").grid(row=0, column=0, padx=5, pady=5)
        self.astronaut_var = tk.StringVar()
        self.astronaut_dropdown = ttk.Combobox(self.medical_frame, textvariable=self.astronaut_var)
        self.astronaut_dropdown.grid(row=0, column=1, padx=5, pady=5)
        self.astronaut_dropdown['values'] = [f"{id} - {name}" for id, name in self.astronauts]

        ttk.Label(self.medical_frame, text="Check-up Date:").grid(row=1, column=0, padx=5, pady=5)
        self.date_entry = ttk.Entry(self.medical_frame)
        self.date_entry.grid(row=1, column=1, padx=5, pady=5)

        ttk.Label(self.medical_frame, text="Heart Rate:").grid(row=2, column=0, padx=5, pady=5)
        self.heart_rate_entry = ttk.Entry(self.medical_frame)
        self.heart_rate_entry.grid(row=2, column=1, padx=5, pady=5)

        ttk.Label(self.medical_frame, text="Blood Pressure:").grid(row=3, column=0, padx=5, pady=5)
        self.blood_pressure_entry = ttk.Entry(self.medical_frame)
        self.blood_pressure_entry.grid(row=3, column=1, padx=5, pady=5)

        ttk.Label(self.medical_frame, text="Weight:").grid(row=4, column=0, padx=5, pady=5)
        self.weight_entry = ttk.Entry(self.medical_frame)
        self.weight_entry.grid(row=4, column=1, padx=5, pady=5)

        ttk.Button(self.medical_frame, text="Add Medical Record", command=self.add_medical_record).grid(row=5, column=0, columnspan=2, pady=10)

    def add_medical_record(self):
    
        astronaut = self.astronaut_var.get().split(' - ')
        if len(astronaut) != 2:
            messagebox.showerror("Error", "Please select an astronaut!")
            return
        astronaut_id = astronaut[0]
        date = self.date_entry.get()
        heart_rate = self.heart_rate_entry.get()
        blood_pressure = self.blood_pressure_entry.get()
        weight = self.weight_entry.get()

        if not astronaut_id or not date or not heart_rate or not blood_pressure or not weight:
            messagebox.showerror("Error", "All fields are required!")
            return

        try:
            astronaut_id = int(astronaut_id)
            heart_rate = int(heart_rate)
            weight = float(weight)
        except ValueError:
            messagebox.showerror("Error", "Invalid input types!")
            return

        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()
        cursor.execute("INSERT INTO medical_records (astronaut_id, check_up_date, heart_rate, blood_pressure, weight) VALUES (?, ?, ?, ?, ?)",
                       (astronaut_id, date, heart_rate, blood_pressure, weight))
        conn.commit()
        conn.close()

        messagebox.showinfo("Success", "Medical record added successfully!")

        self.date_entry.delete(0, tk.END)
        self.heart_rate_entry.delete(0, tk.END)
        self.blood_pressure_entry.delete(0, tk.END)
        self.weight_entry.delete(0, tk.END)

    def view_medical_records(self):
        pass

This code allows us to input and save medical records. It's like conducting health check-ups in our space station's medical bay!

6. Viewing and Updating Records

To complete our Cosmic Health Tracker, let's add a way to view and update records:

    def setup_astronaut_tab(self):
    # ... (previous code remains the same)
        # We need a button to switch to the list of astronauts
        ttk.Button(self.astronaut_frame, text="View Astronauts", command=self.view_astronauts).grid(row=4, column=0, columnspan=2, pady=10)

    def view_astronauts(self):
        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM astronauts")
        astronauts = cursor.fetchall()
        conn.close()

        # Create a new window to display astronauts
        astronaut_window = tk.Toplevel(self.master)
        astronaut_window.title("Astronaut Records")

        for i, astronaut in enumerate(astronauts):
            ttk.Label(astronaut_window, text=f"ID: {astronaut[0]}, Name: {astronaut[1]}, Age: {astronaut[2]}, Nationality: {astronaut[3]}").grid(row=i, column=0, padx=5, pady=5)

    def setup_medical_tab(self):
         # ... (previous code remains the same)
         # We need a button to switch to the list of medical records
         ttk.Button(self.medical_frame, text="View Medical Records", command=self.view_medical_records).grid(row=6, column=0, columnspan=2, pady=10)

    def view_medical_records(self):
        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()
        cursor.execute("""
            SELECT m.id, m.astronaut_id, a.name, m.check_up_date, m.heart_rate, m.blood_pressure, m.weight 
            FROM medical_records m
            JOIN astronauts a ON m.astronaut_id = a.id
        """)
        records = cursor.fetchall()
        conn.close()

        medical_window = tk.Toplevel(self.master)
        medical_window.title("Medical Records")

        for i, record in enumerate(records):
            ttk.Label(medical_window, text=f"ID: {record[0]}, Astronaut ID: {record[1]}, Name: {record[2]}, Date: {record[3]}, Heart Rate: {record[4]}, BP: {record[5]}, Weight: {record[6]}").grid(row=i, column=0, padx=5, pady=5)

These additions allow us to view our stored data. It's like accessing the space station's central database!

7. Error Handling

To make our program more robust, let's add some basic error handling. We'll modify add_astronaut and add_medical_record:

def add_astronaut(self):
    
    #add after nationality line:
    if not name or not age or not nationality:
        messagebox.showerror("Error", "All fields are required!")
        return

    try:
        age = int(age)

    except ValueError:
        messagebox.showerror("Error", "Age must be a number!")
        return
        # ... (rest of the function remains the same)

def add_medical_record(self):

    #add after weight line:
    if not astronaut_id or not date or not heart_rate or not blood_pressure or not weight:
        messagebox.showerror("Error", "All fields are required!")
        return

    try:
        astronaut_id = int(astronaut_id)
        heart_rate = int(heart_rate)
        weight = float(weight)

    except ValueError:
        messagebox.showerror("Error", "Invalid input types!")
        return
        # ... (rest of the function remains the same)

This error handling is like our space station's safety protocols, preventing system crashes and data corruption!

8. Mission Accomplished: Our Complete Astronaut Health Tracker

Congratulations, space coder! You've successfully built a Cosmic Health Tracker for managing astronaut medical data. This program allows you to:

  1. Add new astronauts to the database
  2. Record medical check-up results
  3. View stored astronaut and medical data
  4. Handle potential errors to keep the system running smoothly

If you feel confident in your Python coding space powers, you can modify our code and add other necessary functions, such as:

  • editing astronaut data,
  • editing medical records,
  • and deleting them.

Remember, you can find the complete code for this project in the "Article's code" tab. Feel free to experiment with it and add your own features. Maybe you could add data visualization to track an astronaut's health over time, or implement a feature to generate crew's health reports?

The skills you've learned here:

  • database management in Python,
  • Python GUI creation
  • and error handling

- are crucial not just for space station software, but for many Earth-bound applications too. Keep exploring, keep coding, and who knows? Maybe one day, your code will be running on a real space station!

Happy coding, space explorer!

import sqlite3
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

class CosmicHealthTracker:

    def __init__(self, master):
        self.master = master
        self.create_database()
        
        master.title("Cosmic Health Tracker")
        master.geometry("600x400")

        self.notebook = ttk.Notebook(master)
        self.notebook.pack(expand=True, fill='both')

        self.astronaut_frame = ttk.Frame(self.notebook)
        self.medical_frame = ttk.Frame(self.notebook)

        self.notebook.add(self.astronaut_frame, text='Astronaut Info')
        self.notebook.add(self.medical_frame, text='Medical Records')
        
        self.load_astronauts()
        self.setup_astronaut_tab()
        self.setup_medical_tab()

    def load_astronauts(self):
        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()
        cursor.execute("SELECT id, name FROM astronauts")
        self.astronauts = cursor.fetchall()
        conn.close()
        
    def create_database(self):
        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()

        cursor.execute('''
        CREATE TABLE IF NOT EXISTS astronauts (
            id INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            age INTEGER,
            nationality TEXT
        )
        ''')

        cursor.execute('''
        CREATE TABLE IF NOT EXISTS medical_records (
            id INTEGER PRIMARY KEY,
            astronaut_id INTEGER,
            check_up_date TEXT,
            heart_rate INTEGER,
            blood_pressure TEXT,
            weight REAL,
            FOREIGN KEY (astronaut_id) REFERENCES astronauts (id)
        )
        ''')

        conn.commit()
        conn.close()

    def setup_astronaut_tab(self):
        ttk.Label(self.astronaut_frame, text="Name:").grid(row=0, column=0, padx=5, pady=5)
        self.name_entry = ttk.Entry(self.astronaut_frame)
        self.name_entry.grid(row=0, column=1, padx=5, pady=5)

        ttk.Label(self.astronaut_frame, text="Age:").grid(row=1, column=0, padx=5, pady=5)
        self.age_entry = ttk.Entry(self.astronaut_frame)
        self.age_entry.grid(row=1, column=1, padx=5, pady=5)

        ttk.Label(self.astronaut_frame, text="Nationality:").grid(row=2, column=0, padx=5, pady=5)
        self.nationality_entry = ttk.Entry(self.astronaut_frame)
        self.nationality_entry.grid(row=2, column=1, padx=5, pady=5)

        ttk.Button(self.astronaut_frame, text="Add Astronaut", command=self.add_astronaut).grid(row=3, column=0, columnspan=2, pady=10)
        ttk.Button(self.astronaut_frame, text="View Astronauts", command=self.view_astronauts).grid(row=4, column=0, columnspan=2, pady=10)

    def add_astronaut(self):
        name = self.name_entry.get()
        age = self.age_entry.get()
        nationality = self.nationality_entry.get()

        if not name or not age or not nationality:
            messagebox.showerror("Error", "All fields are required!")
            return

        try:
            age = int(age)
        except ValueError:
            messagebox.showerror("Error", "Age must be a number!")
            return

        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()
        cursor.execute("INSERT INTO astronauts (name, age, nationality) VALUES (?, ?, ?)", (name, age, nationality))
        conn.commit()
        conn.close()

        messagebox.showinfo("Success", "Astronaut added successfully!")

        self.name_entry.delete(0, tk.END)
        self.age_entry.delete(0, tk.END)
        self.nationality_entry.delete(0, tk.END)
        self.load_astronauts()  # Reload astronauts after adding a new one
        self.astronaut_dropdown['values'] = [f"{id} - {name}" for id, name in self.astronauts]
        
    def setup_medical_tab(self):
        ttk.Label(self.medical_frame, text="Astronaut:").grid(row=0, column=0, padx=5, pady=5)
        self.astronaut_var = tk.StringVar()
        self.astronaut_dropdown = ttk.Combobox(self.medical_frame, textvariable=self.astronaut_var)
        self.astronaut_dropdown.grid(row=0, column=1, padx=5, pady=5)
        self.astronaut_dropdown['values'] = [f"{id} - {name}" for id, name in self.astronauts]

        ttk.Label(self.medical_frame, text="Check-up Date:").grid(row=1, column=0, padx=5, pady=5)
        self.date_entry = ttk.Entry(self.medical_frame)
        self.date_entry.grid(row=1, column=1, padx=5, pady=5)

        ttk.Label(self.medical_frame, text="Heart Rate:").grid(row=2, column=0, padx=5, pady=5)
        self.heart_rate_entry = ttk.Entry(self.medical_frame)
        self.heart_rate_entry.grid(row=2, column=1, padx=5, pady=5)

        ttk.Label(self.medical_frame, text="Blood Pressure:").grid(row=3, column=0, padx=5, pady=5)
        self.blood_pressure_entry = ttk.Entry(self.medical_frame)
        self.blood_pressure_entry.grid(row=3, column=1, padx=5, pady=5)

        ttk.Label(self.medical_frame, text="Weight:").grid(row=4, column=0, padx=5, pady=5)
        self.weight_entry = ttk.Entry(self.medical_frame)
        self.weight_entry.grid(row=4, column=1, padx=5, pady=5)

        ttk.Button(self.medical_frame, text="Add Medical Record", command=self.add_medical_record).grid(row=5, column=0, columnspan=2, pady=10)
        ttk.Button(self.medical_frame, text="View Medical Records", command=self.view_medical_records).grid(row=6, column=0, columnspan=2, pady=10)
        
    def add_medical_record(self):
    
        astronaut = self.astronaut_var.get().split(' - ')
        if len(astronaut) != 2:
            messagebox.showerror("Error", "Please select an astronaut!")
            return
        astronaut_id = astronaut[0]
        date = self.date_entry.get()
        heart_rate = self.heart_rate_entry.get()
        blood_pressure = self.blood_pressure_entry.get()
        weight = self.weight_entry.get()

        if not astronaut_id or not date or not heart_rate or not blood_pressure or not weight:
            messagebox.showerror("Error", "All fields are required!")
            return

        try:
            astronaut_id = int(astronaut_id)
            heart_rate = int(heart_rate)
            weight = float(weight)
        except ValueError:
            messagebox.showerror("Error", "Invalid input types!")
            return

        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()
        cursor.execute("INSERT INTO medical_records (astronaut_id, check_up_date, heart_rate, blood_pressure, weight) VALUES (?, ?, ?, ?, ?)",
                       (astronaut_id, date, heart_rate, blood_pressure, weight))
        conn.commit()
        conn.close()

        messagebox.showinfo("Success", "Medical record added successfully!")

        self.date_entry.delete(0, tk.END)
        self.heart_rate_entry.delete(0, tk.END)
        self.blood_pressure_entry.delete(0, tk.END)
        self.weight_entry.delete(0, tk.END)

    def view_astronauts(self):
        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM astronauts")
        astronauts = cursor.fetchall()
        conn.close()

        astronaut_window = tk.Toplevel(self.master)
        astronaut_window.title("Astronaut Records")

        for i, astronaut in enumerate(astronauts):
            ttk.Label(astronaut_window, text=f"ID: {astronaut[0]}, Name: {astronaut[1]}, Age: {astronaut[2]}, Nationality: {astronaut[3]}").grid(row=i, column=0, padx=5, pady=5)

    def view_medical_records(self):
        conn = sqlite3.connect('space_station.db')
        cursor = conn.cursor()
        cursor.execute("""
            SELECT m.id, m.astronaut_id, a.name, m.check_up_date, m.heart_rate, m.blood_pressure, m.weight 
            FROM medical_records m
            JOIN astronauts a ON m.astronaut_id = a.id
        """)
        records = cursor.fetchall()
        conn.close()

        medical_window = tk.Toplevel(self.master)
        medical_window.title("Medical Records")

        for i, record in enumerate(records):
            ttk.Label(medical_window, text=f"ID: {record[0]}, Astronaut ID: {record[1]}, Name: {record[2]}, Date: {record[3]}, Heart Rate: {record[4]}, BP: {record[5]}, Weight: {record[6]}").grid(row=i, column=0, padx=5, pady=5)

if __name__ == "__main__":
    root = tk.Tk()
    app = CosmicHealthTracker(root)
    root.mainloop()