Skip to article frontmatterSkip to article content

Mastering the Basics

The Ohio State University Libraries

Data skills | concepts

  • Python

Learning objectives

  1. Contruct variables, manipulate strings, and loop through lists
  2. Build and navigate dictionaries
  3. Define and use functions
  4. Export data to .csv files

This tutorial is designed to support multi-session workshops hosted by The Ohio State University Libraries Research Commons. It is intended to help the ABSOLUTE beginner, or anyone who is relatively new to Python and working toward confidently applying their Python skills to research projects.

Getting started

Setup Python

A easy way to install Python and essential libraries is by dowloading Anaconda on your personal device. Anaconda is a Python distribution that simplifies package management and deployment. It comes preloaded with over 250 popular for data analysis and visualization—including Pandas, NumPy, and Matplotlib—and allows you to install, update, and manage packages without using the command line, making it especially user-friendly for beginners.

Setup IDE

Integrated Development Environments (IDEs) combine essential coding tools—like editors, terminals, and plugins—into as single application to streamline your workflow. Spyder, included with the Anaconda distribution, is tailored for scientists, engineers, and data analysts. Another excellent option is Visual Studio Code, a versatile IDE that offers real-time feedback as you build and refine your code. Both tools support interactive coding, data exploration and more, making them great choices for beginners and professionals alike.

Absolute vs relative paths

When you run a Python script the folder it runs from is set as the current working directory (cwd). This is where Python looks for files to read and write by default.

  • In VS Code, you can set the working directory by clicking the Explorer icon on the top left of the Activity Bar. Open or create a file in your project folder, and Python will treat that location as the base for storing and accessing files.
  • In Spyder, set the working directory by clicking the folder icon in the upper right corner of the Toolbar.

Relative paths

If your files are stored in the same folder as your Python script, you can use a relative path.

relative_filepath_of_text = "path.txt"

Python interprets this path relative to the current working directory.

Absolute paths

If your files are stored elsewhere, use an absolute path to specify the full location:

absolute_filepath_of_text = "C:/path/to/your/directory/file.txt"

Reading and writing files

Opening a file

To work with a file in Python, you first need to open it. This returns a file object that allows you to read from or write to the file.

Basic Syntax:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
  • file: The path to the file (absolute or relative).
  • mode: Optional. Specifies how the file is opened. Default is r (read mode).

Common file modes

CharacterMeaning
'r'open for reading (default)
'w'open for writing, truncating the file first
'x'open for exclusive creation, failing if the file already exists
'a'open for writing, appending to the end of file if it exists
'b'binary mode
't'text mode (default)
'+'open for updating (reading and writing

Encoding

Use the encoding parameter when working in text mode to specify how characters are interpreted. Common encodings include:

  • utf-8 — Most commonly used and recommended.
  • utf-16 — Uses 2 bytes per character; useful for some international text.
  • utf-32 — Uses 4 bytes per character; supports all Unicode characters directly.
carmen_ohio=open('carmen_ohio.txt', mode='r', encoding='utf-8')
print(carmen_ohio)
<_io.TextIOWrapper name='Carmen_Ohio.txt' mode='r' encoding='utf-8'>

Reading a file

To read a file, open it in read mode (r) and use the .read() method

carmen_ohio=open('carmen_ohio.txt', mode='r', encoding='utf-8').read()
print(carmen_ohio)
Oh come let's sing Ohio's praise
And songs to Alma Mater raise
While our hearts rebounding thrill
With joy which death alone can still
Summer's heat or winter's cold
The seasons pass the years will roll
Time and change will surely[a] show
How firm thy friendship ... OHIO!


These jolly days of priceless worth
By far the gladdest days on earth
Soon will pass and we not know
How dearly we love Ohio
We should strive to keep thy name
Of fair repute and spotless fame
So in college halls we'll grow
And love thee better ... OHIO!


Though age may dim our mem'ry's store
We'll think of happy days of yore
True to friend and frank to foe
As sturdy sons of Ohio
If on seas of care we roll
Neath blackened sky or barren shoal
Thoughts of thee bid darkness go
Dear Alma Mater ... OHIO!
#Alternative - use a with block to open in read mode and use the .read() method 

with open('carmen_ohio.text', mode='r', encoding='utf-8') as file:
    content = file.read()

Writing to a file

To write a file, open it in write mode (w). This will overwrite the file if it already exists.

If you don’t specify a mode, Python defaults to r (read mode), so it’s important to explicity set mode='w' when writing.

open('carmen_ohio_revised.txt', mode='w', encoding='utf-8')
<_io.TextIOWrapper name='carmen_ohio_revised.txt' mode='w' encoding='utf-8'>

Again, this creates an object. To add text to a file, use the .write() method.

open('carmen_ohio_revised.txt', mode='w', encoding='utf-8').write("Let's firm thy friendship again!!!")

Now our file reads:

open('carmen_ohio_revised.txt', mode='r', encoding='utf-8').read()
"Let's firm thy friendship again!!!"
#Alternative - use a with block to open in write mode and use the .write() method 

with open('carmen_ohio_revised.txt', mode='w', encoding='utf-8') as file:
    file.write("Let's firm thy friendship again!!!")

Variables

Python supports a variety of built-in data types, each suited for different kinds of information.

NameAbbrTypeDescriptionExample
StringstrSequenceText“The Ohio State University”
IntegerintNumericWhole numbers1870
FloatfloatNumericDecimal numbers3.14
BooleanboolBooleanTrue/False valuesTrue
ListlistSequenceOrdered, mutable collection[“The Ohio State University” , 1870 ]
DictionarydictMappingKey-value pairs{“institution_name” : “The Ohio State University”,“year_founded” : 1870 }
TupletupleSequenceOrdered, immutable collection(“The Ohio State University”, 1870)
  • Mutuable types: Lists, dictionaries, and strings can be modified after creation.
  • Immutable types: Tuples cannot be changed once defined.

Working with variables

Variables are created using the = operator.

institution_name = "The Ohio State University"
year_founded = 1870
university_facts = {"institution_name": "The Ohio State University", "year_founded" : 1870, "school_colors" : "scarlet & grey", "mascot" : "Brutus Buckeye", "students" : 60046, "endowment": 7.9 }
fact_list = ["The Ohio State University", 1870, "scarlet & grey","Brutus Buckeye", 60046, 7.9 ]

Naming rules

  • Can include letters, digits, and underscores.
  • Must not start with a digit.
  • Cannot contain spaces or special characthers (except _).
  • Must not use reserved Python keywords.

Reserved keywords

False, True, None, and, as, assert, async, await, def, del, elif, else, break, class, continue, except, finally, for, from, global, if, import, in, is, lambda, nonlocal, not, or, pass, raise, return, try, while, with, yield

To check a variable’s type, use the type() function.

type(university_facts)
dict

Basic math operators in Python

Python supports standard arithmetic operations such as addition, subtraction, multiplication, and division. A list of basic math operators is below. For more details, refer to Python’s documentation on math operators.

OperationExpressionResult
Additionx + ySum of x and y
Subtractionx - yDifference of x and y
Multiplicationx * yProduct of x and y
Divisionx / yQuotient of x and y
Floor Divisionx // yQuotient rounded down
Modulusx % yRemainder of x divided by y
Exponentionx ** yx raised to the power of y
Negation-xNegative value of x
Absolute Valueabs(x)Absolute value of x
Convert to Intint(x)Converts x to an integer
Convert to Floatfloat(x)Converts x to a float
Power Functionpow(x,y)Equivalent to x ** y

Example:

x=10
y=15
z=x+y
print(z)
25

Working with strings

In Python, strings represent textual data and are enclosed in either single (') or double (") quotation marks:

'this is a string'
"this is also a string"

The opening and closing quotes much match.

Consider:
"The Readers' Advisory Guide to Horror Fiction"
'"Did you take the trash out?" she asked.'

To include special characthers like quotes within a string, use a backslash ( \ ) to escape them. This tells Python to ignore the character.

'The Readers\' Advisory Guide to Horror Fiction'

Assigning strings to variables

You can assign a string to a variable using the = operator:

banned_book = "Brave New World"

String indexing and slicing

Python uses zero-based indexing, meaning the first character of a string is at position 0.

Access a single character

banned_book[0]
'B'

Slice a substring

To extract a portion of a string, use the following syntax:

string[start index:end index]

The start index is where the slice begins and the end index tells Python where to stop—but it does not include the character at that position.

Example:
Slice the word Brave from the string banned_book:

banned_book[0:5]
'Brave'

If the start index is not included, Python will automatically start the range at the 0 index position.

banned_book[:5]
'Brave'

Negative Indexing

You can also access characters from the end of a string using negative indices:

library = "Thompson Library, 1858 Neil Avenue Mall, Columbus, OH 43210"
zipcode = library[-5:]

zipcode
'43085'

Common string methods

MethodDescription
string.lower()Converts all characters to lowercase
string.upper()Converts all characters to uppercase
string.title()Capitalizes the first letter of each word
string.strip()Removes leading and trailing white space
string.replace('old string', 'new string')Replaces all occurrences of old with new
string.split('delim')Splits the string into a list using the specified delimiter
string.join(list)Joins elements of a list into a string using the specified delimiter.
string.startswith('some string')Returns True if the string starts with the specified text
string.endswith('some string')Returns True if the string ends with the specified text
string.isspace()Returns True if the string contains only whitespace

🔗 For more, see Python String Methods documentation.

Examples:

1. Replace text in a string

Let’s try replacing the word praise in the first sentence of carmen_ohio with wonders using the replace method.

Basic Syntax

string.replace('old string', 'new string')
first_sentence=carmen_ohio[:32]
revised_first_sentence=first_sentence.replace('praise','wonders')

print("original first sentence: "+ first_sentence)
print("revised first sentence: "+revised_first_sentence)
original first sentence: Oh come let's sing Ohio's praise
revised first sentence: Oh come let's sing Ohio's wonders

2. Normalize case

String methods like .lower() and .upper() are useful for standardizing text, especially when comparing values that may differ in capitalization.

Example:

name1 = "McMurty, Larry"
name2 = "Mcmurty, Larry"
name3 = "mcmurty, larry"

#Convert all names to uppercase for consistent comparison
name1_rev = name1.upper()
name2_rev = name2.upper()
name3_rev = name3.upper()

print(name1_rev)
print(name2_rev)
print(name3_rev)
MCMURTY, LARRY
MCMURTY, LARRY
MCMURTY, LARRY

3. Splitting strings

By default, .split() separates strings by spaces. You can also specify a delimiter, such as newline ‘\n’. This returns a list of lines, one for each row in the string.

newline_free_carmen=carmen_ohio.split('\n')
newline_free_carmen
["Oh come let's sing Ohio's praise", 'And songs to Alma Mater raise', 'While our hearts rebounding thrill', 'With joy which death alone can still', "Summer's heat or winter's cold", 'The seasons pass the years will roll', 'Time and change will surely[a] show', 'How firm thy friendship ... OHIO!', '', '', 'These jolly days of priceless worth', 'By far the gladdest days on earth', 'Soon will pass and we not know', 'How dearly we love Ohio', 'We should strive to keep thy name', 'Of fair repute and spotless fame', "So in college halls we'll grow", 'And love thee better ... OHIO!', '', '', "Though age may dim our mem'ry's store", "We'll think of happy days of yore", 'True to friend and frank to foe', 'As sturdy sons of Ohio', 'If on seas of care we roll', 'Neath blackened sky or barren shoal', 'Thoughts of thee bid darkness go', 'Dear Alma Mater ... OHIO!']

If the delimiter is blank, a list of words is returned:

carmen_split=carmen_ohio.split()
carmen_split[0:6] #limit to first 6
['Oh', 'come', "let's", 'sing', "Ohio's", 'praise']

Conditionals and comparisons

Conditionals allow you to control the flow of your program by executing code only when certain conditions are met. Python uses if, elif, and else statements to evaluate whether something is True or False.

Example: Wilbur the Pig

Cute piglet

Let’s say we want to:

  • Print Wilbur’s name if he’s a pig.
  • Compliment him if he’s handsome.
  • Confirm if Charlotte is his best friend.

Step 1: Assign variables

wilbur_species='pig'
wilbur_handsome='handsome'
wilbur_likes_charlotte=True

Step 2: Create conditional statements

if wilbur_species == 'pig':
    print('Wilbur')
    
if wilbur_handsome=='handsome':
    print("He's really cute!") # Use double quotes to handle apostraphes
    
if wilbur_likes_charlotte==True:
    print('Charlotte is Wilbur\'s best friend') # or cancel out the apostrophe
else:
    print('no')
Wilbur
He's really cute!
Charlotte is Wilbur's best friend

Using if, elif, and else

  • if checks the first condition.
  • elif (short for “else if”) checks additional conditions if the first is false.
  • else runs if none of the previous conditions are met.
if wilbur_likes_charlotte==True:
     print("Charlotte is Wilbur's best friend") 
Charlotte is Wilbur's best friend
if wilbur_likes_charlotte==True:
    print('yes')
else:
    print("Charlotte is Wilbur's best friend") 
yes

Comparison operators

OperatorMeaning
==Equal to
!=Not equal to
>Greater than
<Less than
>=Greater than or equal to
<=Less than or equal to

Logical operators

Use these to combine multiple conditions

OperatorMeaning
andTrue if both conditions are true
orTrue if at least one conditions is true
notTrue if the condition is not true

Examples:


if wilbur_species == 'pig' and wilbur_handsome == 'handsome':
    print("Wilbur is a handsome pig!")
Wilbur is a handsome pig!

Is this Wilbur?

guinea pig
y="guinea pig"

if not y:
    print('Wilbur')
else:
    print(y)
guinea pig

Using the in keyword

The in keyword checks if a substring exists within a string.

if 'mouse' not in y:
    print('Not a guinea pig')
Not a guinea pig

Lists and loops

A list is an ordered, mutable collection of items in Python. List are enclosed in square brackets [], and lists are separated by commas.

characters = ['Han Solo', 'Luke Skywalker', 'C3PO', 'R2D2']
type(characters)
list

Lists can contain any data type—even other lists or dictionaries:

random_list = ['Halloween', 'monster', 2024, ['Snickers', 'M&Ms','Mars Bars'],{'dog': 'Stanley','age':7,'color':'black/tan'}]

#IS THIS A LIST?
type(random_list)
list

Accessing list items

Lists use zero-based indexing, just like strings. You can use slicing to extract elements:

list_name[start_index:stop_index:step]

Examples:

  1. Extract the first item from the list characters:
characters[0]
'Han Solo'
  1. Extract the last 3 items from the list characters:
characters[-3:]
['Luke Skywalker', 'C3PO', 'R2D2']
  1. Extract characters from the string han_solo:
han_solo='Han Solo'
han_only=han_solo[0:3]
print(han_only)
Han

Common list methods

MethodDescription
list.append(another_item)Adds an item to end of list
list.extend(another_list)Adds all items from another list
list.remove(item)Removes the first occurence of the item
list.sort(reverse=False)Sorts the list in ascending order
list.reverse()Reverses the order of the list

Examples:

characters = ['Han Solo', 'Luke Skywalker', 'C3PO', 'R2D2']
characters.append('Rey')
print(characters)
['Han Solo', 'Luke Skywalker', 'C3PO', 'R2D2', 'Rey']
characters.remove('Rey')
print(characters)
['Han Solo', 'Luke Skywalker', 'C3PO', 'R2D2']
characters_new = ['Rey','BB-8']
characters.extend(characters_new)
print(characters)
['Han Solo', 'Luke Skywalker', 'C3PO', 'R2D2', 'Rey', 'BB-8']
characters.sort()
print(characters)
['BB-8', 'C3PO', 'Han Solo', 'Luke Skywalker', 'R2D2', 'Rey']
characters.sort(reverse=True)
print(characters)
['Rey', 'R2D2', 'Luke Skywalker', 'Han Solo', 'C3PO', 'BB-8']

Using loops with lists

When working with lists, it’s a good practice to use plural names for your list variables. This makes your code easier to read and understand—especially when you’re iterating through each element.

Python’s for loop allows you to iterate over items in a sequence—such as a list, tuple, dictionary, or string—and execute a block of code for each item.

Basic Syntax

for item in sequence
     #Code to execute for each item

Examples:

  1. Loop through the characters list.
for character in characters:
    print(character)
Rey
R2D2
Luke Skywalker
Han Solo
C3PO
BB-8
  1. Use slicing to print names of the last 3 characters:
for character in characters[-3:]:
    print(character)
Han Solo
C3PO
BB-8
  1. Use conditional statements to add a comment for each character:
for character in characters:
    if character == 'BB-8' or character=='R2D2' or character == 'C3PO':
        print(f"{character} is a robot")
    elif character == 'Luke Skywalker':
        print('Luke is Leia\'s brother')
    elif character == 'Han Solo':
        print('Chewbacca is Han Solo\'s friend')
    elif character == 'Rey':
        print("Rey rocks")
Rey rocks
R2D2 is a robot
Luke is Leia's brother
Chewbacca is Han Solo's friend
C3PO is a robot
BB-8 is a robot

Note the line f"{character} is a robot" in the first conditional statement of the loop. This is known as an f-string, short for formatted string literal.

An f-string is created by placing the letter f directly before the opening quotation mark of a string. This allows you to embed variables or expressions inside the string using curly braces {}. Python will automatically evaluate the expression and insert its value into the string.

Index or enumerate list items

There are several ways to determine the index position of items in a list.

.index()

One way is to use a for loop with the built-in .index() method. This method returns the first occurence of a specified value in the list.

Here’s an example using list of Ohio State University presidents.

presidents=["Edward Francis Baxter Orton Sr","Walter Quincy Scott","William Henry Scott","James Hulme Canfield","William Oxley Thompson",
            "George Washington Rightmire","William McPherson","Howard Landis Bevis","Novice Gail Fawcett","Harold Leroy Enarson",
            "Edward Harrington Jennings","E. Gordon Gee","John Richard Sisson","William English Kirwan","Edward Harrington Jennings",
            "Karen Ann Holbrook","Joseph A. Alutto","E. Gordon Gee","Joseph A. Alutto","Michael V. Drake","Kristina M. Johnson",
            "Peter J. Mohler",'Walter "Ted" Carter, Jr.']

for president in presidents:
    president_index_position=presidents.index(president)
    president_index_position=president_index_position+1
    print(str(president_index_position)+' '+president)
1 Edward Francis Baxter Orton Sr
2 Walter Quincy Scott
3 William Henry Scott
4 James Hulme Canfield
5 William Oxley Thompson
6 George Washington Rightmire
7 William McPherson
8 Howard Landis Bevis
9 Novice Gail Fawcett
10 Harold Leroy Enarson
11 Edward Harrington Jennings
12 E. Gordon Gee
13 John Richard Sisson
14 William English Kirwan
11 Edward Harrington Jennings
16 Karen Ann Holbrook
17 Joseph A. Alutto
12 E. Gordon Gee
17 Joseph A. Alutto
20 Michael V. Drake
21 Kristina M. Johnson
22 Peter J. Mohler
23 Walter "Ted" Carter, Jr.

.enumerate()

A more common and efficient approach is to use the built-in enumerate() function within a for loop.

The enumerate() function returns both the index and the item as you iterate through the list, making your code more readable and avoiding potential issues with methods like .index(), which only returns the first occurrence of a value.

Why use enumerate()?
  • It’s more efficient than calling .index() inside a loop.
  • It handles duplicate values correctly by giving the actual position in the list.
  • It improves readability and reduces the chance of logical errors.

This example asks Python to return two variables from the presidents list, the index position and the president.

for index, president in enumerate(presidents):
    print(index, president)
0 Edward Francis Baxter Orton Sr
1 Walter Quincy Scott
2 William Henry Scott
3 James Hulme Canfield
4 William Oxley Thompson
5 George Washington Rightmire
6 William McPherson
7 Howard Landis Bevis
8 Novice Gail Fawcett
9 Harold Leroy Enarson
10 Edward Harrington Jennings
11 E. Gordon Gee
12 John Richard Sisson
13 William English Kirwan
14 Edward Harrington Jennings
15 Karen Ann Holbrook
16 Joseph A. Alutto
17 E. Gordon Gee
18 Joseph A. Alutto
19 Michael V. Drake
20 Kristina M. Johnson
21 Peter J. Mohler
22 Walter "Ted" Carter, Jr.

This example uses an f-string to make the returned print statement more clear.

for index, president in enumerate(presidents):
    print(f"{president} was the {index} president of The Ohio State University")
Edward Francis Baxter Orton Sr was the 0 president of The Ohio State University
Walter Quincy Scott was the 1 president of The Ohio State University
William Henry Scott was the 2 president of The Ohio State University
James Hulme Canfield was the 3 president of The Ohio State University
William Oxley Thompson was the 4 president of The Ohio State University
George Washington Rightmire was the 5 president of The Ohio State University
William McPherson was the 6 president of The Ohio State University
Howard Landis Bevis was the 7 president of The Ohio State University
Novice Gail Fawcett was the 8 president of The Ohio State University
Harold Leroy Enarson was the 9 president of The Ohio State University
Edward Harrington Jennings was the 10 president of The Ohio State University
E. Gordon Gee was the 11 president of The Ohio State University
John Richard Sisson was the 12 president of The Ohio State University
William English Kirwan was the 13 president of The Ohio State University
Edward Harrington Jennings was the 14 president of The Ohio State University
Karen Ann Holbrook was the 15 president of The Ohio State University
Joseph A. Alutto was the 16 president of The Ohio State University
E. Gordon Gee was the 17 president of The Ohio State University
Joseph A. Alutto was the 18 president of The Ohio State University
Michael V. Drake was the 19 president of The Ohio State University
Kristina M. Johnson was the 20 president of The Ohio State University
Peter J. Mohler was the 21 president of The Ohio State University
Walter "Ted" Carter, Jr. was the 22 president of The Ohio State University

Keep in mind that Python uses zero-based indexing, meaning the first item in a list has an index of 0. To make the output more user-friendly—especially when displaying positions—you can add 1 to each index so that counting starts at 1.

To enhance the script further, you can use a conditional statement to append a superscript to each number (like 1ˢᵗ, 2ⁿᵈ, 3ʳᵈ, etc.), making the output more polished and readable.

for index, president in enumerate(presidents):
    index=index+1
    if index==1 or index==21:
        superscript='st'
    elif index==2 or index==22:
        superscript='nd'
    elif index==3 or index==23:
        superscript='rd'
    elif index>=4 and index<=20:
        superscript='th'
    print(f"{president} was the {index}{superscript} president of The Ohio State University")
Edward Francis Baxter Orton Sr was the 1st president of The Ohio State University
Walter Quincy Scott was the 2nd president of The Ohio State University
William Henry Scott was the 3rd president of The Ohio State University
James Hulme Canfield was the 4th president of The Ohio State University
William Oxley Thompson was the 5th president of The Ohio State University
George Washington Rightmire was the 6th president of The Ohio State University
William McPherson was the 7th president of The Ohio State University
Howard Landis Bevis was the 8th president of The Ohio State University
Novice Gail Fawcett was the 9th president of The Ohio State University
Harold Leroy Enarson was the 10th president of The Ohio State University
Edward Harrington Jennings was the 11th president of The Ohio State University
E. Gordon Gee was the 12th president of The Ohio State University
John Richard Sisson was the 13th president of The Ohio State University
William English Kirwan was the 14th president of The Ohio State University
Edward Harrington Jennings was the 15th president of The Ohio State University
Karen Ann Holbrook was the 16th president of The Ohio State University
Joseph A. Alutto was the 17th president of The Ohio State University
E. Gordon Gee was the 18th president of The Ohio State University
Joseph A. Alutto was the 19th president of The Ohio State University
Michael V. Drake was the 20th president of The Ohio State University
Kristina M. Johnson was the 21st president of The Ohio State University
Peter J. Mohler was the 22nd president of The Ohio State University
Walter "Ted" Carter, Jr. was the 23rd president of The Ohio State University

Building lists with loops

You can create new lists from existing ones by using a for loop along with the .append() method. This is a common and effective way to filter or transform data in Python.

Example: Finding U.S. States That Border the Pacific Ocean

Suppose you have a list of U.S. states and want to create a new list containing only those that border the Pacific Ocean. You can do this by checking each state and appending the matching ones to a new list:

#FIRST WE START BY ASSIGNING AN EMPTY LIST TO A VARIABLE
pacific_states=[ ]

# NEXT WE NEED A LIST OF ALL THE STATES
united_states=["Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Delaware","Florida",
               "Georgia","Hawaii","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana","Maine",
               "Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana","Nebraska",
               "Nevada","New Hampshire","New Jersey","New Mexico","New York","North Carolina","North Dakota",
               "Ohio","Oklahoma","Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota","Tennessee",
               "Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming"]

#THEN WE USE A FOR LOOP WITH A CONDITIONAL STATEMENT TO FIND THE WESTERN STATES
for state in united_states:
    if state=="Alaska" or state=="California" or state=="Hawaii" or state=="Oregon" or state=="Washington":
        pacific_states.append(state)
        
print(pacific_states)
['Alaska', 'California', 'Hawaii', 'Oregon', 'Washington']

Counting items in a list

Knowing how many items are in a list is especially helpful when working with data—such as extracting information from a website or querying a database.

In Python, you can determine the number of elements in a list using the built-in len() function.

len(united_states)
50

Using Counter Variables

While Python provides built-in tools like enumerate() and the .index() method to find the position of items in a list, there are times when using a counter variable can be a simple and effective alternative.

A counter variable allows you to manually track the position of items as you loop through a list. This can be especially useful when you need more control over how positions are counted or displayed.

count=0
for state in united_states:
    count +=1
    print('Starting record '+str(count)+' '+state)
Starting record 1 Alabama
Starting record 2 Alaska
Starting record 3 Arizona
Starting record 4 Arkansas
Starting record 5 California
Starting record 6 Colorado
Starting record 7 Connecticut
Starting record 8 Delaware
Starting record 9 Florida
Starting record 10 Georgia
Starting record 11 Hawaii
Starting record 12 Idaho
Starting record 13 Illinois
Starting record 14 Indiana
Starting record 15 Iowa
Starting record 16 Kansas
Starting record 17 Kentucky
Starting record 18 Louisiana
Starting record 19 Maine
Starting record 20 Maryland
Starting record 21 Massachusetts
Starting record 22 Michigan
Starting record 23 Minnesota
Starting record 24 Mississippi
Starting record 25 Missouri
Starting record 26 Montana
Starting record 27 Nebraska
Starting record 28 Nevada
Starting record 29 New Hampshire
Starting record 30 New Jersey
Starting record 31 New Mexico
Starting record 32 New York
Starting record 33 North Carolina
Starting record 34 North Dakota
Starting record 35 Ohio
Starting record 36 Oklahoma
Starting record 37 Oregon
Starting record 38 Pennsylvania
Starting record 39 Rhode Island
Starting record 40 South Carolina
Starting record 41 South Dakota
Starting record 42 Tennessee
Starting record 43 Texas
Starting record 44 Utah
Starting record 45 Vermont
Starting record 46 Virginia
Starting record 47 Washington
Starting record 48 West Virginia
Starting record 49 Wisconsin
Starting record 50 Wyoming

List Comprehensions

List comprehensions offer a compact way to create new lists by combining a for loop and an optional if condition—all in a single line of code.

Basic Syntax

[expression for item in iterable if condition]

Instead of writing this longer version:

pacific_states=[]
for state in united_states:
    if state=="Alaska" or state=="California" or state=="Hawaii" or state=="Oregon" or state=="Washington":
        pacific_states.append(state)

You can simplify it using a list comprehension:

pacific_states = [state for state in united_states if state=="Alaska" or state=="California" or state=="Hawaii" or state=="Oregon" or state=="Washington"]
print(pacific_states)

Dictionaries

A dictionary is a collection of unordered, changeable (mutable) key-value pairs. Each key is unique and maps to a specific value. Dictionaries are enclosed in curly braces {}, with each key and value separated by a colon : and each pair separated by a comma.

university_facts = {"institution_name": "The Ohio State University", 
                    "year_founded" : 1870, 
                    "school_colors" : "scarlet & grey", 
                    "mascot" : "Brutus Buckeye", 
                    "students" : 60046, 
                    "endowment": 7.9 }

print(university_facts)
{'institution_name': 'The Ohio State University', 'year_founded': 1870, 'school_colors': 'scarlet & grey', 'mascot': 'Brutus Buckeye', 'students': 60046, 'endowment': 7.9}

Accessing dictionary data

Keys

Use .keys() to get a list of all keys.

university_facts.keys()
dict_keys(['institution_name', 'year_founded', 'school_colors', 'mascot', 'students', 'endowment'])

Values

Use .values() to get a list of all values.

university_facts.values()
dict_values(['The Ohio State University', 1870, 'scarlet & grey', 'Brutus Buckeye', 60046, 7.9])

Access a value

Use the key inside square brackets

first_president = {"name":"Edward Francis Baxter Orton Sr", 
              "tenure":"1873-1881"}

print(first_president["name"])
print(first_president["tenure"])
Edward Francis Baxter Orton Sr
1873-1881

Modifying and adding data

  • Add a new key-value pair
first_president["rank"] = "first president"
first_president
{'name': 'Edward Francis Baxter Orton Sr', 'tenure': '1873-1881', 'location': 'Columbus, Ohio', 'rank': 'first president'}

Start with an empty dictionary:

You can begin with an empty dictionary and add key-value pairs as needed.

state_facts={}
state_facts["state"]="Ohio"
state_facts["nicknames"]=["The Buckeye State","Birthplace of Aviation","The Heart of It All"]
state_facts["capital"]="Columbus"
state_facts["population"]=11785935

state_facts
{'state': 'Ohio', 'nicknames': ['The Buckeye State', 'Birthplace of Aviation', 'The Heart of It All'], 'capital': 'Columbus', 'population': 11785935}

Modify an existing value

To update a value in a dictionary, use the dictionary name followed by the key in square brackets, then assign a new value using the equals sign (=).

state_facts["state"]="Michigan"
state_facts["nicknames"]=["The Great Lake State","The Wolverine State","Water (Winter) Wonderland"]
state_facts["capital"]="Lansing"
state_facts["population"]=10077331

state_facts
{'state': 'Michigan', 'nicknames': ['The Great Lake State', 'The Wolverine State', 'Water (Winter) Wonderland'], 'capital': 'Lansing', 'population': 10077331}

Nesting dictionaries

Dictionaries can contain other dictionaries, allowing for more complex data structures.

states={
    "state1":{'name': 'Ohio',
              'nicknames': ['The Buckeye State','Birthplace of Aviation','The Heart of It All'],
              'capital': 'Columbus',
              'population': 11785935},
    "state2":{
        'name': 'Michigan',
        'nicknames': ['The Great Lake State','The Wolverine State','Water (Winter) Wonderland'],
        'capital': 'Lansing',
        'population': 10077331}
    }

states
{'state1': {'name': 'Ohio', 'nicknames': ['The Buckeye State', 'Birthplace of Aviation', 'The Heart of It All'], 'capital': 'Columbus', 'population': 11785935}, 'state2': {'name': 'Michigan', 'nicknames': ['The Great Lake State', 'The Wolverine State', 'Water (Winter) Wonderland'], 'capital': 'Lansing', 'population': 10077331}}

Access a nested dictionary

To access the first state in the dictionary states, use the key for "state1.

states["state1"]
{'name': 'Ohio', 'nicknames': ['The Buckeye State', 'Birthplace of Aviation', 'The Heart of It All'], 'capital': 'Columbus', 'population': 11785935}

Access a nested value

To access the nicknames*for the first state in the dictionary states, use the keys for state1 and nicknames.

states["state1"]["nicknames"]
['The Buckeye State', 'Birthplace of Aviation', 'The Heart of It All']

Looping through a dictionary

Python provides several ways to iterate through the contents of a dictionary, depending on what you need to access:

1. Loop through key-value pairs

Use the .items() method to access both keys and their corresponding values:

for key, value in states.items():
    print(f"\nKey: {key}")
    print(f"\nValue: {value}")

Key: state1

Value: {'name': 'Ohio', 'nicknames': ['The Buckeye State', 'Birthplace of Aviation', 'The Heart of It All'], 'capital': 'Columbus', 'population': 11785935}

Key: state2

Value: {'name': 'Michigan', 'nicknames': ['The Great Lake State', 'The Wolverine State', 'Water (Winter) Wonderland'], 'capital': 'Lansing', 'population': 10077331}

2. Loop through keys only

Use the .keys() method to iterate over just the keys.

for key in states.keys():
    print(f"Key: {key}")
Key: state1
Key: state2

3. Loop through the values only

Use the .values() method to iterate over just the values.

for value in states.values():
    print(f"Value: {value}")
Value: {'name': 'Ohio', 'nicknames': ['The Buckeye State', 'Birthplace of Aviation', 'The Heart of It All'], 'capital': 'Columbus', 'population': 11785935}
Value: {'name': 'Michigan', 'nicknames': ['The Great Lake State', 'The Wolverine State', 'Water (Winter) Wonderland'], 'capital': 'Lansing', 'population': 10077331}

Each method gives you flexibility depending on whether you need the keys, the values, or both.

Looping through a nested dictionary

When working with nested dictionaries—dictionaries that contain other dictionaries as values—you can use a nested for loop to access the inner keys and values.

for outer_key, inner_dict in states.items():
    for inner_key, inner_value in value.items():
        print(f"\nKey: {inner_key}")
        print(f"\nValue: {inner_value}")

Key: name

Value: Ohio

Key: nicknames

Value: ['The Buckeye State', 'Birthplace of Aviation', 'The Heart of It All']

Key: capital

Value: Columbus

Key: population

Value: 11785935

Key: name

Value: Michigan

Key: nicknames

Value: ['The Great Lake State', 'The Wolverine State', 'Water (Winter) Wonderland']

Key: capital

Value: Lansing

Key: population

Value: 10077331
Explanation:
  • The first loop (for outer_key, inner_dict in states.items()) iterates through the outer dictionary.
  • The second loop (for inner_key, inner_value in inner_dict.items()) goes through each inner dictionary.

This approach allows you to access and work with all levels of data in a nested structure.

Examples:
for state in states.keys():
    print(state)
state1
state2
for state in states.values():
    for each_state in state.keys():
        print(each_state)
name
nicknames
capital
population
name
nicknames
capital
population
for state in states.values():
    for each_state in state.values():
        print(each_state)
Ohio
['The Buckeye State', 'Birthplace of Aviation', 'The Heart of It All']
Columbus
11785935
Michigan
['The Great Lake State', 'The Wolverine State', 'Water (Winter) Wonderland']
Lansing
10077331
for each_dictionary in states:
    print(each_dictionary)
state1
state2
for each_dictionary in states:
    print(states[each_dictionary])
{'name': 'Ohio', 'nicknames': ['The Buckeye State', 'Birthplace of Aviation', 'The Heart of It All'], 'capital': 'Columbus', 'population': 11785935}
{'name': 'Michigan', 'nicknames': ['The Great Lake State', 'The Wolverine State', 'Water (Winter) Wonderland'], 'capital': 'Lansing', 'population': 10077331}

Functions in Python

Python includes many built-in functions that help you perform common tasks, such as:

  • print() – displays output
  • type() – returns the data type of a value
  • enumerate() – adds a counter to an iterable

In addition to these, you can also define your own functions to perform specific tasks. This is especially useful when you need to reuse the same block of code multiple times in a program.

What is a function?

A function is a reusable block of code designed to perform a particular task. Functions help make your code more organized, readable, and efficient.

Defining a function

To define a function, use the def keyword, followed by the function name, parentheses (), and a colon :. The code inside the function is indented.

def say_hello():
    print("Hello")

Calling a function

To call or execute a function, simply write its name followed by parentheses.

say_hello()
Hello

Arguments and parameters

When defining a function, you can include parameters inside the parentheses. These parameters act as placeholders for values that will be passed into the function when it’s called. This allows your function to work dynamically with different inputs.

In this example:

  • name is a parameter—a variable defined in the function header.
  • When the function is called, you provide an argument—a specific value that replaces the parameter.
def say_hello(name):
    print(f"Hello, {name}")

Calling the function with an argument

say_hello("Sarah")
Hello, Sarah

This makes your function flexible and reusable with different inputs.

Parameters vs. arguments

  • A parameter is a variable listed inside the parentheses when defining a function. It acts as a placeholder for the value the function will receive.
def function_name(parameter):
    # function body
  • An argument is the actual value you pass into the function when calling it.

function_name(argument)

Positional vs. keyword arguments

When calling a function in Python, you can pass arguments in two main ways: positional and keyword.

1. Positional arguments

By default, Python matches arguments to parameters based on their position in the function call. The first argument is assigned to the first parameter, the second to the second, and so on.

def describe_pet(animal_type, pet_name):
    print(f"\nI have a {animal_type}")
    print(f"\nMy {animal_type}'s name is {pet_name.title()}.")
#FUNCTION CALLED WITH CORRECT POSITIONAL ARGUMENTS    
describe_pet('dog','stanley') 

I have a dog

My dog's name is Stanley.
#FUNCTION CALLED WITH INCORRECT POSITIONAL ARGUMENTS    
describe_pet('stanley','dog') 

I have a stanley

My stanley's name is Dog.
2. Keyword arguments

With keyword arguments, you explicitly specify which value goes to which parameter using the parameter=value syntax. This removes the dependency on the order of arguments.

def describe_pet(pet_name="name",animal_type='species'):
    print(f"I have a {animal_type}")
    print(f"My {animal_type}'s name is {pet_name.title()}.")

pet_description=describe_pet(pet_name='Charlotte', animal_type='spider')
I have a spider
My spider's name is Charlotte.

Return Values from Functions

So far, we’ve used print() to display output from functions. However, functions can also return values using the return statement. This allows you to store the result and use it later.

def format_name(first_name, last_name):
    full_name=f"{first_name} {last_name}"
    return full_name.title()

name=format_name('sarah','murphy')
print(name)
Sarah Murphy

Returning values is useful when you want to process data and use the result elsewhere in your program.

Common Python Errors

Making mistakes is a natural part of learning Python. Don’t worry—error messages are your friends! They help you understand what went wrong and how to fix it.

🔴 SyntaxError

Example messages:

  • SyntaxError: EOL while scanning string literal
  • SyntaxError: invalid syntax

This error usually means:

  • You forgot a colon : at the end of a control structure like a for loop or if statement.
  • You left a string unclosed (missing a quotation mark).
#❌ Missing closing quote
print("It's a wonderful day!)
trees=["maple","walnut","oak"]
#❌ Missing colon in for loop
for tree in trees
    print(tree)

📁 FileNotFoundError

Example message:

This means Python can’t find the file you’re trying to open. Double-check:

#❌ File does not exist in the specified path
open('sample_file.txt').read()

🔢 TypeError

Example message:

This happens when you try to perform an operation on incompatible data types.

#❌ Cannot add a string and an integer
name="Sarah"
name+8
#✅ Check data type
type(name)
#✅ Convert int to str before concatenation
name+str(8)

❓ NameError

Example message:

This means Python can’t find the variable or function you’re trying to use. Common causes:

#❌ Variable 'Name' is not defined
Name

⚙️ AttributeError

Example message:

This occurs when you try to use a method that doesn’t exist for a particular data type.

##❌ Incorrect: enumerate used as a method
trees=["maple","walnut","oak"]
for tree in trees.enumerate():
    print(tree)
##✅ Correct: enumerate used as a function
trees=["maple","walnut","oak"]
for tree in enumerate(trees):
    print(tree)

Export data to a .csv file

You can export data to a .csv file in Python using either the built-in csv module or the powerful Pandas library. Here’s how to do both:

Method 1: Using the csv module

import csv

#####     STEP 1 - CREATE EMPTY DATASET AND DEFINE CSV HEADINGS     ##### 
dataSet=[]
columns=['institution_name','year_founded','school_colors','mascot','students','endowment'] # for CSV headings

#####     STEP 2 - DEFINE FUNCTION TO WRITE RESULTS TO CSV FILE     #####


def writeto_csv(data,filename,columns):
    with open(filename,'w+',newline='',encoding="UTF-8") as file:
        writer = csv.DictWriter(file,fieldnames=columns)
        writer.writeheader()
        writer = csv.writer(file)
        for element in data:
            writer.writerows([element])

#####     STEP 3 - ADD A ROW OF DATA     #####
institution_name= "The Ohio State University" 
year_founded = 1870
school_colors = "scarlet & grey"
mascot = "Brutus Buckeye"
students = 60046
endowment = 7.9

dataSet.append([institution_name,year_founded,school_colors,mascot,students,endowment])

#####     STEP 4 - EXPORT TO CSV     #####
writeto_csv(dataSet,'data/university_facts.csv',columns)

Method 2: Using Pandas

import pandas as pd

#####     STEP 1 - CREATE DATAFRAME TO STORE ROWS     #####
results=pd.DataFrame(columns=['institution_name','year_founded','school_colors','mascot','students','endowment'])

#####     STEP 2 - DEFINE EACH ROW AS A DICTIONARY    #####
university_facts = {"institution_name": "The Ohio State University", 
                    "year_founded" : 1870, 
                    "school_colors" : "scarlet & grey", 
                    "mascot" : "Brutus Buckeye", 
                    "students" : 60046, 
                    "endowment": 7.9 }

#####     STEP 3 - CONVERT EACH DICTIONARY ROW TO A DATAFRAME    #####
add_row_to_results=pd.DataFrame(university_facts, index=[0])

#####     STEP 4 - CONCATENATE RESULTS EACH ROW TO RESULTS DATAFRAME    #####
results=pd.concat([add_row_to_results, results], axis=0, ignore_index=True)

#####     STEP 5 - EXPORT THE RESULTS DATAFRAME TO A CSV FILE    #####
results.to_csv('data/university_facts.csv', encoding='utf-8')