Lab 2 Solutions: Data Classes and Programming Fundamentals

PSTAT 5A - Summer Session A 2025

Author

Instructor: Narjes Mathlouthi

Published

July 7, 2025

Introduction

This document contains the complete solutions to Lab 2: Data Classes and Programming Fundamentals. Each task is solved with explanations to help you understand the concepts.

Lists

Task 1 Solution

Create a list containing the elements 1, "hi", 3.4, and "PSTAT 5A". Assign this list to a variable called list1.

# Solution
list1 = [1, "hi", 3.4, "PSTAT 5A"]
print(list1)
[1, 'hi', 3.4, 'PSTAT 5A']

Task 1 (cont’d) Solution

Run the code type(list1).

# Solution
print(type(list1))
<class 'list'>

Explanation: The output shows <class 'list'>, confirming that list1 is indeed a list object.

Indexing

Task 2 Solution

Create a list with the numbers 1 through 10, inclusive, and assign this to a variable called x.

# Solution
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Alternative using range:
# x = list(range(1, 11))
print(x)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Run the code x[1].

# Solution
print(x[1])
2

Run the code x[0].

# Solution
print(x[0])
1

Explanation: - x[1] returns 2 (the second element, since indexing starts at 0) - x[0] returns 1 (the first element)

Task 3 Solution

Create a list called x that contains the elements 1, "two", 3.5, "four", and "five five". Answer the questions and verify.

# Create the list
x = [1, "two", 3.5, "four", "five five"]

# Predictions as comments:
# 1. type(x) would output: <class 'list'>
# 2. type(x[1]) would output: <class 'str'>
# 3. x[0] would output: 1

Now verify the answers:

# Verify answers
print("1. type(x):", type(x))
print("2. type(x[1]):", type(x[1]))
print("3. x[0]:", x[0])
1. type(x): <class 'list'>
2. type(x[1]): <class 'str'>
3. x[0]: 1

Explanation: 1. type(x) returns <class 'list'> because x is a list 2. type(x[1]) returns <class 'str'> because x[1] is “two”, which is a string 3. x[0] returns 1, the first element of the list

Tables

First, let’s install and import the datascience module:

# Install datascience if needed (uncomment if necessary)
# !pip install datascience
from datascience import *

Task 4 Solution

Read the list of methods for Table objects and write down three different methods:

# Three Table methods with descriptions:
# .with_columns(): adds specified columns to a table
# .select(): selects specific columns from a table and returns a new table
# .where(): filters rows based on a condition and returns a new table with matching rows
# .num_rows: returns the number of rows in the table
# .num_columns: returns the number of columns in the table

Task 5 Solution

Create the professor table:

# Solution
profs = Table().with_columns(
    "Professor", ["Dr. Swenson", "Dr. Wainwright", "Dr. Mouti"],
    "Office", ["South Hall", "Old Gym", "Old Gym"],
    "Course", ["PSTAT 130", "PSTAT 120A", "PSTAT 126"]
)

profs
Professor Office Course
Dr. Swenson South Hall PSTAT 130
Dr. Wainwright Old Gym PSTAT 120A
Dr. Mouti Old Gym PSTAT 126

Select the column called Course from profs:

# Solution
profs.select("Course")
Course
PSTAT 130
PSTAT 120A
PSTAT 126

Create a new table called profs_new with an additional row:

# Solution
profs_new = profs.with_row(["Dr. Ravat", "South Hall", "PSTAT 120B"])
profs_new
Professor Office Course
Dr. Swenson South Hall PSTAT 130
Dr. Wainwright Old Gym PSTAT 120A
Dr. Mouti Old Gym PSTAT 126
Dr. Ravat South Hall PSTAT 120B

Explanation: The .with_row() method adds a new row to the existing table. We provide the values in the same order as the columns.

Filtering Tables Example

# Create example table for filtering
table1 = Table().with_columns(
    "Course", ["PSTAT 5A", "PSTAT 120A", "PSTAT 130"],
    "Units", [4, 4, 4],
    "Instructor", ["Mathlouthi", "Johnson", "Smith"]
)

# Filter for courses taught by Mathlouthi
table1.where("Instructor", "Mathlouthi")
Course Units Instructor
PSTAT 5A 4 Mathlouthi
# Try filtering for an instructor that doesn't exist
table1.where("Instructor", "Wilson")
Course Units Instructor

Arrays

Task 6 Solution

Make a list and array with the same elements and compare operations:

# Create list and array
my_list = [1, 2, 3]
my_array = make_array(1, 2, 3)

print("List:", my_list)
print("Array:", my_array)
List: [1, 2, 3]
Array: [1 2 3]
# Sum operations
print("sum(my_list):", sum(my_list))
print("sum(my_array):", sum(my_array))
sum(my_list): 6
sum(my_array): 6
# Addition with scalar - this will cause an error for lists
try:
    result = my_list + 2
    print("my_list + 2:", result)
except TypeError as e:
    print("Error with my_list + 2:", e)
Error with my_list + 2: can only concatenate list (not "int") to list
# Addition with scalar works for arrays
print("my_array + 2:", my_array + 2)
my_array + 2: [3 4 5]

Explanation: Arrays support element-wise operations (like adding 2 to each element), while lists do not. Lists use + for concatenation, not arithmetic.

Comparisons

Task 7 Solution

Compare "statistics" and "Statistics":

# Solution
print('"statistics" < "Statistics":', "statistics" < "Statistics")
print('"Statistics" < "statistics":', "Statistics" < "statistics")

# Additional comparisons to understand the pattern
print('ord("S"):', ord("S"))
print('ord("s"):', ord("s"))
"statistics" < "Statistics": False
"Statistics" < "statistics": True
ord("S"): 83
ord("s"): 115

Answer: When Python compares strings, capital letters are given precedence (they have “lower” ASCII values). Capital letters come before lowercase letters in ASCII ordering, so "Statistics" < "statistics" returns True.

Task 8 Solution

Create arrays and compare element-wise:

# Solution
x = make_array(1, 2, 3)
y = make_array(2, 3, 1)

print("x:", x)
print("y:", y)
print("x < y:", x < y)
x: [1 2 3]
y: [2 3 1]
x < y: [ True  True False]

Explanation: Python compares arrays element-wise, returning an array of boolean values: - 1 < 2True - 2 < 3True
- 3 < 1False

Conditionals

Task 9 Solution

Predict and verify the conditional statement:

# Prediction: x will be "goodbye"
# Reasoning: x = 2, so x < 2 is False, but x < 3 is True

# Run the code:
x = 2

if x < 2:
    x = "hello"
elif x < 3:
    x = "goodbye"
else:
    x = "take care"

print("Result:", x)
Result: goodbye

Explanation: Since x = 2: - x < 2 is False (2 is not less than 2) - x < 3 is True (2 is less than 3) - So the elif condition executes, setting x = "goodbye"

Functions

Task 10 Solution

Three functions we’ve used in this Lab:

# Three functions used in this lab:
# 1. type() - returns the data type of an object
# 2. print() - displays output to the screen
# 3. make_array() - creates an array from the given elements
# Additional: sum(), len(), range()

Task 11 Solution

Write a Celsius to Fahrenheit conversion function:

# Solution
def cent_to_far(c):
    """Convert Celsius to Fahrenheit using the formula F = (9/5) * C + 32"""
    fahrenheit = (9/5) * c + 32
    return fahrenheit

# Test the function
print("cent_to_far(0):", cent_to_far(0))    # Should return 32
print("cent_to_far(20):", cent_to_far(20))  # Should return 68
cent_to_far(0): 32.0
cent_to_far(20): 68.0

Explanation: The conversion formula is F = (9/5) × C + 32. Our function correctly implements this formula.

Task 12 Solution

Write a parity function to determine if a number is even or odd:

# Solution
def parity(x):
    """Returns 'even' if x is even, 'odd' if x is odd"""
    if x % 2 == 0:
        return "even"
    else:
        return "odd"

# Test the function
print("parity(2):", parity(2))  # Should return 'even'
print("parity(3):", parity(3))  # Should return 'odd'

# Additional tests
print("parity(10):", parity(10))
print("parity(15):", parity(15))
parity(2): even
parity(3): odd
parity(10): even
parity(15): odd

Explanation: The modulus operator % returns the remainder of division. If x % 2 == 0, then x is divisible by 2 (even). Otherwise, it’s odd.


Complete Examples and Additional Practice

Here are some additional examples that demonstrate the concepts:

Advanced List Operations

# List slicing examples
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print("First 5 elements:", numbers[:5])
print("Last 3 elements:", numbers[-3:])
print("Every other element:", numbers[::2])
First 5 elements: [0, 1, 2, 3, 4]
Last 3 elements: [7, 8, 9]
Every other element: [0, 2, 4, 6, 8]

Table Operations

# More complex table operations
students = Table().with_columns(
    "Name", ["Alice", "Bob", "Charlie", "Diana"],
    "Grade", [85, 92, 78, 96],
    "Year", ["Sophomore", "Junior", "Freshman", "Senior"]
)

# Multiple operations
high_performers = students.where("Grade", are.above(90))
print("High performers:")
high_performers.show()

# Sort by grade
sorted_students = students.sort("Grade", descending=True)
print("\nStudents sorted by grade:")
sorted_students.show()
High performers:
Name Grade Year
Bob 92 Junior
Diana 96 Senior

Students sorted by grade:
Name Grade Year
Diana 96 Senior
Bob 92 Junior
Alice 85 Sophomore
Charlie 78 Freshman

Array Operations

import numpy as np

# Array mathematical operations
scores = make_array(85, 92, 78, 96, 89)
print("Original scores:", scores)
print("Curved scores (+5):", scores + 5)
print("Squared scores:", scores ** 2)
print("Average score:", np.mean(scores))
Original scores: [85 92 78 96 89]
Curved scores (+5): [ 90  97  83 101  94]
Squared scores: [7225 8464 6084 9216 7921]
Average score: 88.0

Summary

This lab covered fundamental Python data structures and programming concepts:

  • Lists: Mutable, mixed-type collections with zero-based indexing
  • Tables: Structured data with named columns for data analysis
  • Arrays: Homogeneous collections supporting element-wise operations
  • Comparisons: Boolean logic and various comparison operators
  • Conditionals: Decision-making with if/elif/else statements
  • Functions: Creating reusable code blocks with proper documentation

These concepts form the foundation for data analysis and programming in Python!