Chapter 2 Introduction to Python

2.1 Vocabulary

  • Library
  • String
  • Integer
  • Float
  • List
  • Boolean
  • Array
  • Vector
  • Matrix
  • Variable
  • f-String

2.2 Introduction

New technologies and the introduction of coding to scientific fields has made solving complex problems as easy and quick as ever. Python is a tool which we can use to easily perform these complex calculations. This software heavily impacted the field of computational neuroscience, where the intricate processes of the brain can now be modeled and translated into the function of a computer. This opens up thousands of doors for new technologies and new discoveries about the brain, as well as how we can potentially recreate brain function virtually. In this chapter, we will explore the basics of Python, how to use it, its syntax, and its function. We will go over different data types and libraries, and how to use the built in tools in Python and these libraries in order to work with data, solve mathematical equations, and how to use Python to understand concepts of computational neuroscience.

2.3 Libraries

In Python, we have tools called “libraries”. We will create an analogy where it should be clear the purpose of libraries in Python. Libraries are places you go to to read information discovered by other individuals already. You could figure out the derivative of “2x,” but it could take a lifetime of work to do this. Instead, why not pick up a calculus book from the library and follow its instructions.
That is how to view libraries. Libraries are pre-written chunks of code–made from other great programmers–which can be pulled from to make writing new code more efficient. It’s important to implement certain libraries if they contain functions and methods to make your job easier. If code already exists, use it. For example, imagine I know I am going to work with irrational numbers and it will be annoying to type out the number pi. There is a library called numpy that can do it for me. Below, I will demonstrate how to utilize the library.

import numpy as np
number_pi = np.pi
print(number_pi)

# Output: 3.141592653589793

Where the variable we declared ‘number_pi’ is the number pi! Note: Variables are before the equal sign and the information stored in them is what is after the equal sign. We dive deeper into assignment statements and variables later on. All we had to do was use the import statement, put the library we wanted to import and for time sake we call it “as np” to make it quicker to type. To use what is in the library you must type what you are importing it as a period in front and then type the function/method you want to utilize.

Note: Functions are blocks of code that can be executed by calling that function’s name. A method on the other hand is a specific action that an object can perform because that method is associated with that object’s class. We dive into data types/classes later on so stay tuned!

import library as something
something.method()/function()

Some libraries that are especially important for scientific computing include:

There are a variety of libraries out there and there is probably a library out there that can make your life easier!

2.4 Data Types

In Python, variables store values where each value is of a certain data type. Different data types serve for different functionality and purposes. Certain data types have built in functions in Python and here we will quickly outline the main kinds of data types and their common uses.

2.4.1 String

String data types will usually appear in-between two quotation marks. They are essentially textual data which can be stored within a variable. String type data will never be numerical.

2.4.1.1 Example 1:

“Bates College” is a string data type. If we put this data type in a variable say: college = ‘Bates College’

Here’s how this would look in Python:

Note the function “%whos” returns a list of every variable and its data type already established in this workbook.

The college variable is of type string. Strings are great when you want to print out a message to a user or get input. There are a lot more uses for strings but these are the main points to take away for now.

2.4.2 Integers

Integer data types are simply numbers without a decimal. For example, 1 is an integer BUT 1.0 is not an integer, it is a float. We will talk about floats soon. Integers are a great tool when doing computations in Python. Python is really good at a variety of arithmetic operations and integers are the data types to access these arithmetic operations!

2.4.3 Floats

Float data types are like integers but now we are dealing with decimal points. Here 1.0 is float, 5.66686 is a float, and so on and so forth. Floats are also able to access the arithmetic tools built in python and are also a great tool to use when dealing with problems that call for them. Moreover, when precision is essential in a project utilizing floats is the way to go!

2.4.4 Lists

Lists are data types that will appear with brackets outside and be filled with a variety of objects inside of it.

2.4.4.1 Example 2:

Here we see the theList object has the data type list where it carries other data types inside of it. Lists are great when you need to store a variety of data in one place. As you will see later lists have a large set of built in functions in python as well that are very beneficial for a variety of projects.

2.4.5 Boolean

A Boolean data type is either True or False, and this binary data type is what python reads when deciding to do certain tasks. For example, if Python reads a task as being False python will not execute its instructions and if True, Python then begins to do the tasks laid for it.

2.4.6 Arrays

Arrays are a helpful tool which allow us to store multiple data points all in one place. Another way to think of arrays is by storing a variety of elements being stored as a unit. We can refer to individual elements in an array by utilizing an index which will be explored later on.

The beauty of arrays is that they are a broad category of a kind of data type. Specific kinds of arrays are known as vectors and matrices which we can easily create using the numpy library. There are many different types of arrays. The two we will learn about in this chapter are vectors and matrices.

2.4.7 Vectors

Vectors are slightly different from lists. Vectors are created from the np.array call where it has one row and a designated amount of columns. Every vector has its own respective length, which can be found using the len() function. Note the length of a vector is going to be the number of columns we assigned it.

2.4.7.1 Example 3:

A vector would look like [1, 2, 3, 4, 5, 6], which has a length of 6 as there are 6 data points/columns. Here it is shown in Python:

Note that the first print() function is printing the contents of the vector, whereas the second print() function is printing the length of the vector.

2.4.8 Matrices

Matrices are essentially like vectors but have more than one row.

2.4.8.1 Example 4:

[1, 2, 3] [4, 5, 6]

This matrix has two rows and thus a length of 2 where we see the length is correlated with the number of rows a matrix contains. Thus, its .shape() would be [2,3].

Here’s how it would show up in Python:

Note: If you ever are curious about an object’s data type use type(object) and you will get back the type of the object.

When performing calculations with specific data types, the data types must match up. For instance, a string cannot be subtracted from an integer, nor can a float be multiplied by a Boolean.

2.4.9 Variable assignment

Placing a single = sign after a block of text assigns whatever is placed after the equals sign to a variable, whatever is before the equals sign. This is helpful to shorthand while coding, as well as to assign short, descriptive names to complex data types.

Here is an example of how to do this:

dividend = 100
divisor = 20
quotient = dividend / divisor
print(quotient)

# 5.0

Here, the variable “dividend” is assigned to 100, the variable “divisor” is assigned to 20, and we are calculating the variable “quotient” by dividing these two variables. These variables can be plugged directly into the equation in order to not have to “hard-code” these numbers; that is, input actual numbers into the equation in case the variable values have to be changed later, the code will still function the same way.

Note: to actually perform the “is equal to” calculation, it’s important to use two equals signs (that is, ==) in order to do so.

2.4.10 f-Strings

Whenever we print out a string we can sometimes run into some conflict. Here is an example.

aNumber = 4

The variable aNumber is an integer. If we type the following:

# Example 1
print('This is the number aNumber')

# Example 2
print('This is the number' +aNumber)

# Example 3
print('This is the number'+str(aNumber))

Then we would obtain the following print statements:
‘This is the aNumber’ An error since it is invalid syntax. This is because aNumber is not a string. ‘This is the number 4’

Thus, the third option is a valid way to print out objects that are not by default string, however, there is a quicker way to do this using formatting strings.

print(f'Words go in here and the next word is {not string type})

The output will be the string and what is in between the curly brackets will be automatically turned into a string and added to the overall string where it was placed. This is awesome in terms of saving time and writing beautiful print statements for the user.

2.4.10.1 Example 5:

voltage = '+35'
phase = 'repolarizing'
print(f'When the voltage hits {voltage} mV, the neuron enters the {phase} \
phase of the action potential.")

Here, we use an f-string to insert information about an action potential into a sentence explaining this action potential. First, we define the variables, then place them in curly brackets within the sentence where we want it to show up.

These f-strings have other amazing features embedded in them where we can, for example, designate the number of decimal places we want a float value to show.

2.4.10.2 Example 6:

random_float = 4.567

print(f’We want to see two decimal places for the random float {random_float:.2f}’
# We want to see two decimal places for the random float 4.57.

This is just one example of its incredible uses but keep exploring other features! Click me to get your feet wet with some examples!

2.5 For loops

For loops are an incredible tool we can use to quickly perform calculations which are looped a certain number of times. They essentially run through a set of instructions a specified number of times while simultaneously running through different data sets in order to see the outcome of these instructions throughout all the data. Here’s an example of how we would use a for loop in computational neuroscience.

2.5.0.1 Example 7:

We are going to create a for loop that lists the resting potential of six different neurons within the text “The resting potential of a neuron is at __mV”.

First, we are going to create a vector containing six different resting potentials. We need to import numpy in order to create a vector, so that is our first step. We save numpy as np so we don’t have to type out “numpy” each time we want to pull from that library. The next step is to create the vector using the np.array([]) function.

Our next step is to start the for loop. We start with the word “for”, which triggers the start of the for loop. We next define the variable, which is going to be [i] in this example. Next, we use the command “in”, which defines the range of the for loop. Next, we define our vector “rate” that we will loop over in each iteration. We finish off this line with a colon “:”.

After the for loop has been started, we have to place a command below it. We indent the next line, then place our command. This can be any mathematical equation, but for this example, we are going to use the “print()” command. We place “print()” after the indent, then state the text, as well as how we want the variable to be processed by the function. Note that in this example, we must name the variable [i] as a string, as that’s what the function is set up to process.

Here’s how this looks in Python:

import numpy as np
rate = np.array([-90, -80, -85, -70, -65, -75])

for i in rate:
  print('The resting potential of the neuron is at ' +str(i) + 'mV')
  
# The resting potential of the neuron is at -90 mV
# The resting potential of the neuron is at -80 mV
# The resting potential of the neuron is at -85 mV
# The resting potential of the neuron is at -70 mV
# The resting potential of the neuron is at -65 mV
# The resting potential of the neuron is at -75 mV

Note that the loop ran through until it processed every item in the vector, and completed the function respectively. It thus printed each item on the list separately into the assigned text.

For loops are incredibly useful, as they can calculate a function with a multitude of data sets, as long as the function remains the same. For instance, it can sort items out of a list, or perform a physics calculation over and over again with different data each time. They save a lot of time in using Python to perform calculations, and they’re an incredibly important tool in the field of computational neuroscience as well. For instance, they can be used to calculate the action potentials of a set of neurons with varying resting potentials, which we can store in a vector.

2.6 If-Elif-Else Statements

If-Elif-Else statements are an easy way to sort data depending on whether or not it fits a certain criteria or not. It essentially tells the computer, “if this happens, then this should be the result. Else, this other result should occur.” Elif is short for “else-if”, which is a middle-ground between else and if demands. “If this occurs, this should be the result. Else if this occurs, this second result should occur. Or else, this third result should occur.” These are helpful in determining what criteria a piece of data can be sorted under. Here’s an example of how an if-else statement can be used in Python.

2.6.0.1 Example 8:

For this example, we are going to place an if-else statement inside of a for loop. This will help us quickly sort through multiple pieces of data. This block of code will help us sort through different neuron voltages and determine whether the neuron is in the process of depolarizing/repolarizing or if it is hyperpolarized. We will start again by importing numpy, as we need it to create a vector. We will then create a vector which contains a series of different voltages to be sorted, between -90 and 30.

The next step is to start the for loop. We set our variable as i and plug our vector “voltage” into function “in”, then follow by a colon.

Next, we start our if-else statement. For our if statement, we will establish whether a neuron is in a depolarizing/repolarizing state by seeing if its voltage is above or equal to the average resting potential of a neuron, -70V. If this statement is true, the function will print “depolarizing/repolarizing”. The else statement states that if the variable is not greater than or equal to -70, it must be in the hyperpolarizing state, and thus it will print “hyperpolarizing”. The for loop will run this test on each set of data in the vector, thus sorting them by whether or not they are a depolarizing/repolarizing voltage or a hyperpolarizing voltage.

Here’s what this would look like in Python.

import numpy as np

voltage = np.array([-65, -90, 30, -70, 10, -80, 30])

for i in voltage:
  if i >= -70:
    print('Depolarizing/Repolarizing')
  else:
    print('Hyperpolarizing)
    

# Depolarizing/Repolarizing
# Hyperpolarizing
# Depolarizing/Repolarizing
# Depolarizing/Repolarizing
# Depolarizing/Repolarizing
# Hyperpolarizing
# Depolarizing/Repolarizing

As you can see, Python printed a list of either “Depolarizing/Repolarizing” or “Hyperpolarizing” which responds to the criteria we placed in the if-else statement in correspondence to the vector.

This example shows how we can use if-else statements in computational neuroscience. They are very useful in running through criteria and if a data set matches up with this set criteria.

2.7 Conditional statements

Here we will quickly demonstrate some conditional statements using pseudo-code. These will be supplementary to when we dive into logic statements!

When thinking of AND statements:

Condition -> If it is raining AND if it is cold:  
    Action -> wear a jacket  

We wear a jacket when both events/conditions are true.

When thinking of OR statements:

Condition -> If it is raining OR if it is cold:  
    Action -> wear a jacket  

We wear a jacket when either events/conditions are true.

2.8 Logic statements

In Python when we get to difficult projects we may have to lay out complex instructions for Python to interpret. For example, we may want to print out a string if an object equals some value and if it doesn’t equal some value, we then want to print out another kind of string. To do this logical statements are essential.

2.8.1 “And”, “Or”, “Not”

Let us understand each of these logic operators. Let us have x and y be some conditional statements we have declared. The “and” operator is usually used when we want Python to read both condition statements to be true to run.

 If x and y are true:
     Do these instructions
     

Here x AND y must be seen as true to run the code below the logic.

The “or” operator is usually used when we want python to read either conditional statement to be true to run.

If x or y are true:
    Do these instructions
    

Here x can be true to run the code inside the if statement. The y can be true to run the code below. Both can be true to run the code. However, if both are false then the code does not run as the statement is now False.

The “not” operator flips the boolean output of a statement. Imagine x is True and y is False:

If x and not y are true:
    Do these intructions
    

We know x is True and y is False. However, the not in front of y makes it become True meaning Python reads the logic statement as true and executes the instructions below.

2.9 While loops

While loops are not a completely new concept; in fact, they are very similar to what we’ve already learned. They are a combination of for loops and if statements. While loops are conditioned to keep them running until that condition is deemed false.

2.9.0.1 Example 9

To create a variable (x) which adds 5 every time it loops through until it gets to 25, we would use a while loop while x is less than 25. In this case, the while loop runs until x = 25, then the while loop would stop once x = 25.

Here’s what this would look like in Python:

x = 0

while x < 25:
  x = x + 5
  print(x)
  
# 5
# 10
# 15
# 20
# 25

The function printed every number of x + 5 between 0 (the starting point which was established outside the loop), and 25, the maximum range. It stopped printing after x = 25, thus, the while loop worked. The loop kept running when the condition was still considered true, as in, x < 25. Once the condition became false, and x = 25, the loop stopped running.

While loops, like for loops, are also very useful in computing repeat mathematical equations. We can use this in computational neuroscience to model the repeated firing of a neuron which will stop as soon as it performs a specific neuronal function or completes a task. While loops and for loops can be used in junction to mimic neuronal firing behavior.

While loops can also be dangerous, however. If inputted incorrectly, while loops will never stop and will run forever, which Python is not fond of. The next example explores this phenomenon.

2.9.0.2 Example 10

x = 10

while 10 < x:
  y = x + 2

In this example, y as a variable is not defined, and there is never any command to change the value of x to be anything other than 10. Thus, the condition is always true and the loop will never stop running, so the cell will never stop running and Python will crash.

When should for loops be used versus while loops? For loops should be used when you need to run through a function a specified number of times, perhaps with a different data set each time. While loops, on the other hand, are used to loop through a function an unspecified number of times until the condition in the function is proven false. While loops are dependent on the outcome of each loop through the function to keep running, whereas for loops are dependent on the number of specified runs through the loop to keep running.

2.10 Summary

In this chapter, we learned some basic functions of Python, as well as how these concepts apply to the field of computational neuroscience. We learned about data types, including strings, integers, floats, lists, booleans, vectors, and matrices. We learned how to use logic statements to perform basic commands in Python. We learned about what a Python library is and how to import it, as well as how to use basic commands of the famous libraries Numpy or Matplotlib to further Python’s capabilities. We learned how to use f-strings to return specific pieces of data from a list. Lastly, we learned how to use for loops and while loops to perform repeat functions, what the difference between them is, and how they can be used in neuroscience contexts. We went over the importance of computer programming and how it has impacted our ability to perform science in the modern world, as well as the directions it may take us in neuroscience fields.

2.11 Example Python Problems

Example 1:
In programming, it’s crucial to be specific, detailed, and consistent in the format. The computer has a few basic commands it can do, so you need to be creative about how you’ll lay out the steps. With this in mind, how would you explain to a computer how to get pizza from a pizza restaurant?

Solution (outline):

  • You would first need to give the computer directions to the pizza restaurant
  • Walk up to the West facing door
  • Put its hand on the handle and pull open the door
  • Step forward into the building.
  • Proceed to the counter, which is on the left side of the building
  • Look at the types of pizza there are and decide which one it wants
  • Ask the cashier for the pizza it wants
  • Wait for pizza, take its box and follow the signs to exit
  • Open East facing doors to exit

Example 2:
The type() function tells you what type of data a certain variable is. Predict what Python will return for the following commands:

a.) type (“hello world”)
b.) type(747)
c.) type(3.14)

Solution:

a.) string
b.) integer
c.) float

Example 3:
Python is a simple programming language and doesn’t naturally come with all of the functions you might need. However, there is no reason to worry. Because Python is so ubiquitous, you can find downloadable packages of code to perform things you might otherwise sink hours into programming. One of these packages is numpy which performs many mathematical calculations that Python doesn’t come equipped with. Here are some examples of numpy functions:

# exponential
numpy.exp(x)

# square root
numpy.sqrt(x)

# natural log
numpy.log(x)

In order to use these functions you must first import the package into your notebook which can simply be done with the import function:

import numpy

Example 4: Write code to do the following and print them:

a.) \(e^8\)
b.) \(\sqrt{55+31}\)
c.) \(\ln(664/41)\)

Solution:

# part a
print(numpy.exp(8))

# part b
print(numpy.sqrt(55+31))

# part c
print(numpy.log(664/41))

Example 5: “If” statements are rather straightforward. You tell Python what to do if a particular circumstance is true. For example:

# pick a random integer between 1 and 10
x = np.random.randint(10)

# print "okie dokie" for if x is small, but print "nokie dokie"
# for larger values
if 4>x:
  print("okie dokie")
else:
  print("nokie dokie")

In this example we are using the numpy.random.randint function to generate a random number between 0-9 and storing it in the variable x. This is because the numpy.random.randint function begins counting at 0 and is not inclusive of the last digit. The if statement then tells Python that if the randomly generated number is less than four print okie dokie and if not print nokie dokie. You can run this code multiple times and see the changes.

Example 6: Now try it yourself. Imagine you’re playing the lottery and your numbers are 3, 22, 55, and 31 and numbers are selected between 0 and 150, you win if any of your numbers are selected. Write an “if” statement that returns “I’m loaded!!!” if your numbers are not selected, print “better luck next time”.

  • Hint: the “==” symbols are used to show equivalency.
  • “Or” is a function that can be used in conjunction with “if” statements.

Solution:

# print a random integer between 1 and 56
x = numpy.random.randint(57)

# check to see if x is a winning number
if x==3 or x==22 or x==55 or x==31:
  print("I'm loaded!")
else:
  print("Better luck next time!")

# check what number was chosen  
print(x)

Example 7: Imagine you are cleaning up at the end of your birthday party. You are tired and hungry from a long day of having fun. You are wondering how many slices of pizza are left in each of the 5 pizza boxes, and you decide to write an algorithm that will look through each pizza box and count the number of remaining slices.

Follow the comments below to understand what each line of this code does:

# We are importing the package numpy which has built in functions 
# that will make coding easier and more efficient.
import numpy

# We are defining the total number of pizza boxes that we need 
# to examine.
totalBoxes = 5

# Start counting the number of pizza slices. Since we haven't 
# started counting, we will start at zero.
count = 0

# Here we are initializing the for loop. We are telling Python 
# to look at each box in the range of totalBoxes.
for box in range(totalBoxes):
  # We’ve indented here because we are working inside the for loop.
  
  # The numpy.random.randint() function is selecting a random 
  # number between 0 and 16 (we use 17 because the numpy random 
  # function is not inclusive of the last digit). This will 
  # represent the number of slices left in this box.
  slices = numpy.random.randint(0, high=17)
  
  # We are telling Python that if there is at least one slice in
  # the box, we should increase the count and print the number of 
  # slices found.
  if slices > 0:
    count += slices
    print('I have found {} slices!'.format(count))
  
  # "Else" tells Python what to do if there is no pizza in this box.
  else:
  
    #Print is indented inside the else statement because you want to 
    # print ("Nooooooo!!!") if the else statement needs to be used.

    print("Nooooooo!!!")

2.12 Conceptual Exercises for Learning Python

  1. How does Python read code?

  2. Compare and contrast the function of brackets and parentheses.

  3. How is a string different from a list, and given their respective scenarios what characters should be used?

  4. How is a tuple different than a list, and given their respective scenarios what characters should be used?

  5. Why is indentation important when using writing code in Python, and how can it affect your cell outcome?

  6. Describe the four most common data types (int, float, bool, str) that variables can be assigned to and describe each one.

2.13 Coding Exercises for Learning Python

  1. Define two variables, one called varOne that represents the value 20 and one called varTwo that represents the value 5:
  1. Creating a new variable called addVar, write a code that will add varOne andvarTwo.
  2. Creating a new variable called divVar, write a code that will divide varOne andvarTwo.
  3. Finally, multiply your two new values (from parts a + b), and assign this to the variable multVar. Hint: use basic addition, divison, and multiplication commands rather than making your own function.
  1. Using the variable name L1:
  1. Create a list of five different food items and print the list.
  2. Write a line of Python code that will print only the 3rd and 5th food in your list from part a.

Using variable name L2: c. Create a second list with three sport names and print the list. d. Write a line of Python code that will sort your list from part c alphabetically.

  1. Create a verbal description of what this code block is doing.
import numpy as np

data = np.array([4, 6, 4, 4, 4, 6, 6, 4, 6])
for x in data:
  if x > 5:
    print('Condition 1')
  else:
    print('Condition 2')
  1. Create a vector from 5 to 15 (non-inclusive) in increments of 2. Then write a line of code that will print the square of each value in the vector.

  2. Create a matrix of zeros with 3 rows and 6 columns. Then, create a 2x4 matrix where the first row lists ice cream flavors and the second row lists soda flavors.

  3. Write a for loop that will start at the lowest temperature you experienced this week and end at the highest temperature you experienced (in one degree increments). Inside your loop, use an if…else statement that prints whether each temperature is even or odd.