Python Refresher

Back to the basics

Tuesday, August 26, 2025

Python Refresher

  • This lesson is designed to help you refresh your Python skills.
  • To work through this lesson, open a Python interpreter of your choice and copy each code snippet into a code cell.
    • Marimo is the recommended environment for this lesson.
    • Alternatively, create a new Python file or Jupyter notebook and copy the code snippets into it.
    • You can also try using the web-based Python shell but working with multiple lines of code can be tricky.

Tip

Use the little “Copy” icon in the top right corner of each code block to copy the code.

Basic Data Types

Python comes with a lot of built in fundamental data types (and libraries have even more!) that we need to understand in order to build our programs. Here are some of the most common that you should be familiar with.

  • Strings
  • Integers / Floats
  • Lists
  • Dictionaries
  • Tuples + str()

Strings

  • immutable data type
    • cannot change directly
    • must make a copy to change
  • lots of built-in operations
# let's define a few strings
a = "hello"
b = " world"

# we can see how many characters are in a string with the len command
print(len(a), len(b))

Try this out in a live Marimo Notebook

String Operations

  • Comparing strings
print(a == b)
  • Iterating through strings
for letter in a:
    print(letter)
  • Indexing or slicing strings
print("Indexing a string: ", a[3])
print("Slicing a string: ", a[0:3])
print("Reversing a string with slicing: ", a[::-1])
  • Concatenating strings
print(a+b)
print(a + b + "!")
  • Looking for specific characters or words
print("e" in a)

Bad String Operations

  • Concatenating strings and numbers does not work. Data types must match!
x = "1"
y = 2
print(x+y)  # this will cause an error
  • Casting Strings
# Change the variable x to an integer:
result = int(x) + y
print(f"Adding two numbers: {result}")

# Change the variable y to a string:
result = x + str(y)
print(f"Concatenating a string and a number: {result}")

f-strings

  • fstring.help
  • Use f-strings to format strings easily.
  • Saves you from complex concatenation and formatting.
  • Does not add weird spaces automatically.
  • Avoid dealing with data type mismatches.
name = "Dan"
age = 21
print(f"Hello, my name is {name} and I am {age} years old.")

one = 1
two = 2
print(f"{one} + {two} = {one + two}")

Integers and Floats

  • int data types represent whole numbers.
  • float data types represent decimal values.
# define some values
a = 2
b = 5
x = 1.2
y = 1.8
z = 1.0
  • Simple integer operations. What type do we get?
print(a + b, type(a + b))  # what would you expect? what did you actually get?
print(a - b, type(a - b))  # same as above?
  • What happens if we have one value that is an integer and one that is a float?
print(a + x, type(a + x))
print(a + z, type(a + z)) # what if the float is a whole number? 2 + 1 = 3, right?

Warning

The distinction between int and float feels simple, but implementations can cause huge side effects.

Integer and Float Operations

  • Turns out that any time a decimal is involved Python will actually “promote” the integer value into a float even if there is no remainder. This is true even if both of the initial values are integers
print(a / b, type(a / b))
  • What about if we cast integers to floats?
print(float(2)) # that feels right, but what about the other way?
print(int(x))  # this will truncate the decimal
print(int(y))  # this will truncate the decimal
print(int(z))  # this will truncate the decimal

Note

int(1.999) and int(1.001) both become 1. Python converts integers to floats by dropping the decimal completely.

  • Bonus: Float values are only maintained to a certain level of precision, which can result in rounding errors. This can have a large impact on multi-step calculations.
print(4.9 - 4.845)  # what do you expect? what do you actually get?

Lists

  • very common, versatile data type; can hold different data types
  • can be sorted, indexed, and sliced like strings
  • mutable, so we can change items without making copies
list1 = ["e", "a", "d", "c", "b"] # explicitly defining a list of characters with []
list2 = list("eadcb") # casting to list
list3 = [1, 2, 4, 5, 3] # list of numbers
list4 = [1, "b", 3, "d", 5] # mixed list
  • sorting lists
list1.sort() # this happens in place; your original ordering has been lost
print("list1 after .sort() :", list1)
print("sorted() returns", sorted(list2))
print("Original list2 after calling sorted() on it:", list2)
  • Concatenating lists together
print(list1 + list3)
  • Appending items to the end of a list
list4.append("6")  # modifies the list in place
print(list4)

List Operations

  • Embedding a different list into a list. Let’s start by making a copy of our original list
list5 = list1.copy() # now we can add a list to the list
new_list = ["f", "g", "h"]
list5.append(new_list)
print(list5)
  • Combining lists
list6 = list1.copy()
list6.extend(new_list)
print(list6)
  • Manipulating individual parts of a list
list6[0] = "1" # changing an element of the list
print(list6)
list6.remove("1") # deleting an element
print(list6)
list6.insert(0, "d") # add an element to a list in a specific spot
print(list6)

# like with strings we can also index and slice lists
print("Here is the 3rd element: ", list6[2])
print("Here are the first 3 elements: ", list6[0:3])

Dictionaries

  • store information in key:value pairs
  • keys must be unique, but values can repeat
  • values can be any data type, including more dictionaries
simple_dict = {"a": "apple", "b": "banana", "c": "cantaloupe"}
print(simple_dict)

print(simple_dict["a"]) # we access values in the dictionary by using the key

keys = simple_dict.keys() # we can get a list of all of the keys
print(keys)
values = simple_dict.values() # also all of the values
k_v = simple_dict.items() # or a combination
print(values)
print(k_v)
# Can you figure out how to sort this dictionary into a different order?

More Complex Dictionary

  • Can you figure out how to access the various nested portions?
other_dict = {
    "bob": {
        "age": 25,
        "profession": "plumber",
        "hobbies": ["video games", "snowboarding", "knitting"],
    },
    "cassidy": {
        "age": 42,
        "profession": "programmer",
        "hobbies": ["dancing", "cooking"],
    },
    "obi-wan": {
        "age": 19,
        "profession": "jedi",
        "hobbies": ["hyper drive repair", "laser swords", "sith hunting"],
    },
}

Tuples

  • Like a list, they can store various data types
  • Cannot be sorted or modified directly
  • Immutable, so we make a copy when we do operations
  • Useful for guaranteeing order and “unpacking” values
  • Unpacking = automatically assigning values to variables
# define a tuple using the () format
tuple1 = (3,1,2)
tuple2 = (4,1,1)
# we can also define a tuple of one value by adding a comma after it
tuple3 = (5, )
# if we have an iterable such as a list we can also cast that to a tuple
tuple4 = tuple([5])

Tuple Operations

  • Sorting a tuple with the .sort() method will produce an error
tuple1.sort()
  • What about with sorted()?
sorted_tuple = sorted(tuple2)  # this will turn the tuple into a list
print(sorted_tuple)
# if we want it to be a tuple again we will have to cast it back to a tuple
sorted_tuple = tuple(sorted_tuple)
print(sorted_tuple)
  • Unpacking (requires the same number of variables as the tuple contains)
a,b = tuple2  # what went wrong?
print(a)
print(b)