464 views
<style> h3 { border-bottom: 1px solid #ccc; } section { margin-bottom: 2rem; padding: 0em 1em; padding-bottom: 1em; border-radius: 4px; background-color: #f7f7f7; border: 1px solid #ccc; } summary { font-weight: bolder; } summary:hover { text-decoration: underline; } .todo { color: #ff00ff; border: 2px dashed #ff00ff; padding: 0em 1em; border-radius: 5px; //display: none; // UNCOMMENT TO HIDE TODOs } </style> # Lab 6: Learning to use Python (Fall 2025) We would really appreciate some feedback on the course! This is totally anonymous: https://docs.google.com/forms/d/e/1FAIpQLSceXyT2IXv5ElQbfxk01IHpxPSJpWFhKEcklSe2GJZyEm36dg/viewform?usp=publish-editor ## Learning Objectives In this lab, you will: - Explore the differences between Java and Python - Understand Python’s limitations in OO programming - Start building some proficiency in python-style programming ## Setup **Environment setup**: Make sure your VSCode is set up as per our [setup guide](https://docs.cs200.io/s/vscode-python-setup-guide), and that you can [run the test files from HW0](https://docs.cs200.io/s/python-stencil-setup-guide#) to make sure your setup is working.  If you have issues during the setup process, see [here](https://docs.cs200.io/s/python-stencil-setup-guide#Troubleshooting). <!-- If you have issues with this process, see [this Ed post](https://edstem.org/us/courses/32789/discussion/2444354) with FAQs about Python setup from HW0.   --> :::info <details><summary><b><i>Note:</i> Having trouble running Python files?</b></summary> If you’re still having issues with Python libraries/modules when running the HW0 test files (eg. errors like “module not found”), you can still work on this lab and fix the errors later.  If you have time in lab, the course staff may be able to help--otherwise, [look here for troubleshooting instructions](https://docs.cs200.io/s/python-stencil-setup-guide#Troubleshooting), and then feel free to ask in Ed or come to hours.  While we don’t need the extra libraries for this lab, you will need them for your later projects so it’s important to make sure you have this working early! ::: </details> **Stencil code**: You can clone the stencil code from using this [Github Classroom link](https://classroom.github.com/a/OkH_615H). You can use the **[Python stencil setup guide](https://docs.cs200.io/s/python-stencil-setup-guide)** for instructions on how to open the stencil in VSCode. ## Intro Brown Health Services is trying to redesign their electronic health record system (EHR). Their current EHR is Java-based, but health services would like to explore the pros and/or cons that a Python-based EHR system might have. Python seems like a great option because it has a lot of flexibility for building classes and data structures; how might they use this flexibility to their advantage or disadvantage? This lab will help introduce you to working with Python and highlight the differences between a similar program written in both languages.  ## Java Classes vs. Python Classes First, familiarize yourself with the structure of the code in Java. You can find the Java code in the `java-src` directory of the stencil project–you can just click on the files in VSCode to open them (no need to open IntelliJ).   The Java code contains a `Visit` class that represents a single visit with a single patient. These Visits are stored in an `ArrayList` in the `HealthRecord` class, along with the patient’s name, blood type, and age. Finally, a `HashMap` in the main method stores each patient’s health record with unique IDs as their keys. In Python, we can define classes with the following syntax: ```python class ClassName: def __init__(self, inputs): # constructor ... def some_function(self, inputs): # method ... ... # other class methods ``` Look at the Python code in `lab7-stencil.py` to see how this syntax is used to create a `Visit` class that corresponds to the Java version. In Python, class name conventions are identical to Java. However, functions, fields, parameters, and variables should be written in snake_case, in which all letters are lowercase with words separated by underscores. For example: `my_variable` and `exciting_new_method`. ### Task 1-A Using the `Visit` class as an example, translate the `HealthRecord` constructor from the Java code into Python, keeping the same parameters and fields (name, age, blood type, and visits). For more guidance, see our [Java to Python guide](https://docs.cs200.io/going-to-python-from-java) and [Python style guide](https://docs.cs200.io/python-style-guide). :::info <details><summary><b>What is <code>self</code>?</b></summary> In Python, the <code>self</code> keyword acts like the <code>this</code> keyword in Java, referring to a class’s own methods and attributes. Contrary to Java, however, <code>self</code> is always required when referring to class fields. When defining a constructor and methods for a class, the <code>self</code> keyword is always the first parameter. ::: </details> ### Task 1-B To practice creating and working with objects in Python, write code to create both a `Visit` and a `HealthRecord` at the end of `lab7-stencil.py`. Note that unlike in Java, this code does NOT need to be inside a class or `main()` method. Also write a couple of expressions that extract field values or otherwise manipulate the fields of the objects. Here’s an initial line to create a `HealthRecord` as an example: ```python HR1 = HealthRecord("bruno", 85, [], "O") ``` :::info <details><summary><b><i>Note:</i> Testing Guidelines</b></summary> As a general rule, write expressions in your file to try out and experiment with all of the methods that you write in this assignment. We aren’t asking you to write formal test cases (we'll do this in HW4), but we do want you to be comfortable using the definitions that you wrote. ::: </details> :::success **Checkpoint!** Call over a TA to check your work. ::: ## Filter, Lambda, and List Comprehensions  ### Task 2 In the Python `HealthRecord` class, implement `above_temp_for` using a for loop. You can do this by translating the Java method `visitsAboveTemp` method located in the Java `HealthRecord` class, which returns a list of visits where a patient had above a certain temperature. The method takes in an integer value called `temp` that represents the threshold temperature and returns the list of visits where the patient had a temperature above the threshold. ## Filter and Lambda As you may have seen from Racket/ReasonML or from the early OO track problems, lambda and higher order functions can be vastly useful, and they exist in Python as well! As a refresher, lambda functions are functions that do not need to be declared/initialized using “def” or “definition” (in Racket) and are also known as anonymous functions. They are very convenient when defining functions that have extremely simple functionality (i.e. adding two numbers or comparing two numbers), and they are often passed into other functions: ``` my_fund = lambda a, b: a + b # Lambda in Python to add two numbers ``` We created a `Function<>` object in [Lab 6](https://docs.cs200.io/3AW_PFdyQaCsjW9K9waWWA#Task-5) that is essentially a lambda! In the next task, you will need to use the above lambda syntax to use Python's filter function, `filter`: ```python some_list = [1,2,3,4,5] filtered = filter(lambda x: x > 2, some_list) for x in filtered: print(x) # Prints 3,4,5 ``` ### Task 3 In the `HealthRecord` class, implement `above_temp_filter`, which uses `filter` and `lambda` to produce the same functionality as `above_temp_for`. ## List Comprehensions Python also allows developers to quickly filter and modify a list without having to use a for loop. List comprehensions follow the below syntax: ```python newlist = [expression for item in iterable if condition == True] # taken from W3Schools ``` This might look a bit overwhelming, so let's look at a few examples of for loops and how they would be written with list comprehensions. ```python my_list = [1,2,3,4,5] result_list = [] # Making new list with only items greater than two # Using for loop for x in my_list: if x > 2: result_list.append(x) # Using list comprehension result_list = [x for x in my_list if x > 2] # result_list will be [3,4,5] ------------- my_list = [1,2,3,4,5] result_list = [] # Making new list with all original items multiplied by two # Using for loop for x in my_list: result_list.append(x * 2) # Using list comprehension result_list = [(x * 2) for x in my_list] # result_list will be [2,4,6,8,10] ``` Oftentimes, to enact the desired behavior, the expression, condition, or both may be changed. And as we saw above, we do not always need to include a condition. ### Task 4 In the `HealthRecord` class, implement `above_temp_comp` which uses a list comprehension to produce the same functionality as `above_temp_for`.  :::success **Checkpoint!** Call over a TA to check your work. ::: ## Dictionaries in Python In Python, dictionaries are the equivalent of Java’s HashMaps. Dictionaries can be defined using the following syntax: ```python some_dict = { # Syntax for making a dictionary with some initial values key1: value1, key2: value2, key3: value3 } # example: another_dict = {"a": 1, "b": 2} # adding a new key-value pair to the dictionary some_dict[key4] = value4 # note: to access a list of the values of a dict, use .values() # some_dict.values() would return [value1, value2, value3, value4] # likewise, to access the keys, use .keys() # some_dict.keys() would return [key1, key2, key3, key4] ``` ### Task 5 At the bottom of your Python file, create a **global** (outside of any class) dictionary, `patient_records`, that maps patient ids to patient health records. Populate your dictionary with some data so that you can use it to try out the methods for tasks 6 and 7. ### Task 6 Implement a global method, `total_blood_count` that takes in a string bloodtype (which will be one of the items from the array `BloodTypes` at the top of the file) and returns the total number of patients that have type bloodtype according to the global dictionary `patient_records`. **Use either a list comprehension or a filter in your implementation**. :::info **Hint**: `len([a, b, c])` returns `3` ::: ### Task 7 Implement a global method, `total_age_blood_count` that takes in a string `bloodtype` (which will be one of the items from the array `BloodTypes`) and an int `age`. `total_age_blood_count` returns the total number of patients older than `age` that have type `bloodtype` according to the global dictionary `patient_records`. **Use either a list comprehension or a filter in your implementation.** :::success **Checkpoint!** Call over a TA to check your work. ::: ## OO Python As you may have seen by now, it is sometimes remarkably difficult to keep track of different variables' types. Python isn’t as demanding of good OO programming as Java is. As such, it is possible for us to replace certain data structures that might take the form of a class in Java with other data structures such as dictionaries in Python.  :::info <details><summary><b><i>Example:</i> <code>Visit</code></b></summary> An example in this lab is the `Visit` class: because our `Visit` class is relatively simple in that it only serves as a shell for more data, we can subsume it with a dictionary and store the data that way. `HealthRecords.visits` would subsequently take the form of a list of dictionaries.  ::: </details> ### Task 8 Modify your `HealthRecords` class so that `HealthRecords.visits` is a list of dictionaries and each visit is represented by a dictionary instead of an instance of the `Visit` class. :::success <details><summary><b><i>Hint:</i> Task 8</b></summary> Instead of a `Visit` class with fields for temperature, weight, etc., we want to store that data in a dictionary instead. What part of a dictionary is the name of a field analogous to? What about the data stored in that field? ::: </details> ## DataClasses At this particular clinic, each patient usually gets a blood pressure or white blood cell count lab performed. These are the **only** two types of lab that can go in the patient’s HealthRecord; all other types of labs are incompatible with this clinic’s electronic healthcare records. In order to mimic some of the more robust OO capabilities that Java has, Python has a dataclass library that we can import and use. Dataclasses are essentially classes that are designed to purely hold data, and they don’t typically have any methods associated with them. :::info **Example**: Here's how to create a `dataclass`: ```python @dataclass class Course: """Class for keeping track of a Brown Course""" department: str courseNumber: int credits: float ``` ::: </details> ### Task 9 An import statement is already included at the top of the stencil code. Create two dataclasses:  - `BloodPressure` should have 2 fields: - `Systolic` - `Diastolic` - `WhiteCellCount` should have 1 field, keeping track of the count ### Task 10 In your visit dictionaries, create a key that maps to a list of labs performed on a given visit. Then implement an `add_labs` method that takes in a lab report and appends it to the end of the `labs` list in the dictionary.  :::info <details><summary>Is there anything stopping us from adding a string to the <code>labs</code> field?</summary> We don't want our `labs` to contain the wrong types of data. Luckily for us, Python has a `type()` method! We can us it like this: ``` x = "Hello" print(type(x) == str) #Output: True y = 0 print(type(y) == float) #Output: False ``` </details> ::: How do Java and Python’s type systems differ? Be prepared to explain the differences to your TA in the checkoff.  :::success **Final Checkpoint** Congratulations! You completed this week’s lab. Call a TA over to get checked off. ::: ## **💡Applications💡** - **Scripting & Automation:** Python’s concise syntax and list comprehensions let you write file-processing or data-cleaning scripts in just a few lines. - **Data Filtering & Analysis:** Using `filter`, `lambda`, and comprehensions is a core part of data-science pipelines for cleaning and transforming datasets (e.g., logs, CSVs). - **Lightweight OOP:** `@dataclass` makes it trivial to define data containers for use in web APIs, configs, or simple domain models without boilerplate. - **Dictionary-Driven Configs:** Python dictionaries power JSON/YAML parsing and dynamic lookups in automation tools and microservices. - **Interview Prep:** Mastery of Python features—lambdas, comprehensions, dataclasses—aligns directly with real-world code and common coding interview questions. *** _Please let us know if you find any mistakes, inconsistencies, or confusing language in this or any other CSCI0200 document by filling out the_ [_anonymous feedback form_](https://docs.google.com/forms/d/e/1FAIpQLSdmeYWU8_8v9fizxUs_3Fq6Ddsn8Tmas3tkL63ALA6XaZ5Tuw/viewform)_._