3  Variables, Data Types, and Python Input/Output

3.1 Commenting code

Commenting a code may have several purposes in programming, such as:

  • Describe what is going to happen in a sequence of code

  • Document who wrote the code or other ancillary information

  • Turn off a line of code - perhaps temporarily

3.1.1 Single-line Comments

Use # before the comment. Everything after # on the same line is ignored by Python.

#Computing number of hours of lecture in this course
print("Total lecture hours of STAT201=",10*3*(5/6))
Total lecture hours of STAT201= 25.0

3.1.2 Multi-line Comments (for documentation or explanation)

While technically Python doesn’t have multi-line comments, we often use triple-quoted strings for that purpose, especially in function/method docstrings:

"""
This is a multi-line comment.
It's technically a string, but can be used like a comment.
Good for longer explanations.
"""
"\nThis is a multi-line comment.\nIt's technically a string, but can be used like a comment.\nGood for longer explanations.\n"

More commonly, triple quotes are used for docstrings of a function (will be covered in the python function chapter):

def greet(name):
    """
    This function takes a name as input
    and prints a greeting message.
    """
    print("Hello,", name)

You can access these docstrings with:

print(greet.__doc__)

    This function takes a name as input
    and prints a greeting message.
    

3.1.3 Practice exercise 1

Which of the following lines is a comment:

  1. #this is a comment

  2. ##this may be a comment

  3. A comment#

3.2 Variables

In programming, a variable is a named container that stores information your program can use and manipulate.

Think of a variable like a labeled box where you can put a value (like a number, word, or object), and then refer to that box by its label later in your code. It allows you to store, access, and manipulate data in your program.

3.2.1 Variable Declaration

  • You can create a variable by assigning a value to it using the assignment operator = .

For example:

x = 10 
name = "Alice" 
pi = 3.14 
is_active = True 

Variable Naming Rules:

  • Names must start with a letter (a-z, A-Z) or an underscore (_).
  • Names can only contain letters, numbers (0-9), and underscores.
  • Names are case-sensitive (name and Name are different variables).
  • Reserved keywords (e.g., if, for, while) cannot be used as variable names.

There are certain reserved words in python that have some meaning, and cannot be used as variable names. These reserved words are:

Best Practices:

Python style guide: Please refer to the python style guide for best coding practices, such as naming variables, using spaces, tabs, and styling the different components of your code.

For example:

# use descriptive variable names:
total_price = 100
# use snake_case for variable names
user_age = 25

3.2.2 Dynamic Typing

Variables in Python are dynamically typed, meaning you don’t need to specify their type when declaring them. The type of a variable is determined by the value assigned to it.

For example:

x = 10 # x is an integer
y = x # y is also an integer

3.2.3 Checking Variable Types

You can use the type() function to check the type of a variable.

x = 10
print(type(x)) 

y = "Python"
print(type(y))  
<class 'int'>
<class 'str'>

3.2.4 Practice exercise 2

Which of the following variable names are valid?

  1. var.name

  2. var9name

  3. _varname

  4. varname*

Which of the following statements is an assignment statement:

  1. x = 5

  2. print(x)

  3. type(x)

  4. x + 4

3.3 Data types

Python provides several built-in data types for storing different kinds of information in variables. These data types can be broadly categorized into primitive data types and collection (containers) data types. While collection data types will be covered later, this chapter focuses on primitive data types, which are used to represent a single value.

3.3.1 Primitive Data Types

They represent a single value. In Python, primitive data types include:

  • String (str): A sequence of characters (e.g., "hello", 'world').
  • Integer (int): Whole numbers (e.g., 10, -3).
  • Floating-point number (float): Numbers with decimals (e.g., 3.14, -2.7).
  • Boolean (bool): Logical values True or False.
  • None type (None): Represents the absence of a value.

3.3.2 Practice exercise 3

What is the datatype of the following objects?

  1. ‘This is False’

  2. “This is a number”

  3. 1000

  4. 65.65

  5. False

3.3.3 Commonly Used Built-in methods associated with each data type

Each data type comes with its own set of built-in methods that help you interact with the data.

3.3.3.1 Strings

Strings are sequences of characters and are immutable in Python.

3.3.3.1.1 Single quotes ' and double quotes " to define strings

in Python, you can use either single quotes (') or double quotes (") to define strings. Both are functionally equivalent, and you can choose based on preference or readability. Here’s an example:

# Using single quotes
string1 = 'Hello, world!'
print(string1)

# Using double quotes
string2 = "Hello, world!"
print(string2)
Hello, world!
Hello, world!

When to use one over the other

  • Single quotes (') are often preferred for simple strings without embedded quotes.
  • Double quotes (") are useful when your string contains a single quote, as it avoids the need for escaping:
# Single quote in a double-quoted string
message = "It's a beautiful day!"
print(message)

# Double quote in a single-quoted string
message = 'He said, "Hello!"'
print(message)
It's a beautiful day!
He said, "Hello!"

Escaping quotes: If your string contains both single and double quotes, you can use the backslash (\) to escape them:

# Escaping single quotes in a single-quoted string
string_with_escape1 = 'It\'s a sunny day.'
print(string_with_escape1)

# Escaping double quotes in a double-quoted string
string_with_escape2 = "He said, \"Hello!\""
print(string_with_escape2)
It's a sunny day.
He said, "Hello!"

You can also use triple quotes (''' or """) for strings that span multiple lines or contain both types of quotes without escaping:

multi_line_string = """This string spans
multiple lines and can include 'single quotes' and "double quotes"."""

print(multi_line_string)
This string spans
multiple lines and can include 'single quotes' and "double quotes".
3.3.3.1.2 String Concatenation
  • Use the + operator to join strings together.
  • All operands must be strings; otherwise, you’ll get a TypeError.
# Basic Concatenation
greeting = "Hello"
name = "Alice"
message = greeting + ", " + name + "!"
print(message)

# Concatenating String Literals
print("Python" + " is " + "fun!")

# Concatenating with Variables
lang = "Python"
level = "beginner"
print("I'm learning " + lang + " as a " + level + " programmer.")
Hello, Alice!
Python is fun!
I'm learning Python as a beginner programmer.
3.3.3.1.3 String Repetition

String repetition is achieved using the * operator. It creates a new string by repeating an existing string a specified number of times.

# Creating Patterns
print("*" * 10)
**********
repeat_count = 4
print("Python! " * repeat_count)
Python! Python! Python! Python! 

Below are Commonly used Methods for strings:

  • len(): returns the length of a string
  • lower(): returns a string with every letter of the original in lowercase
  • upper(): returns a string with every letter of the original in uppercase
  • replace(x,y): returns a string with every occurrence of x replaced by y
  • count(x): counts the number of occurrences of x in the string
  • index(x): returns the location of the first occurrence of x
  • format(): format strings
  • isalpha(): returns True if every character of the string is a letter

For a more comprehensive list of string methods, please refer to here

# Example Methods:
s = "Hello, World!"

# Returns the length of the string
len(s) 
print("the length of the string is", len(s))

# Converts string to uppercase
s.upper()
print("the string in uppercase is", s.upper())

# Converts string to lowercase
s.lower()
print("the string in lowercase is", s.lower())

# Capitalizes the first character of the string
s.capitalize()
print("the string with first letter capitalized is", s.capitalize())

# Finds the first occurrence of a substring
s.find("World")
print("the first occurrence of the substring is at", s.find("World"))

# Replaces a substring with another string
s.replace("World", "Python")
print("the string after replacement is", s.replace("World", "Python"))

# Splits the string into a list
s.split(", ")
print("the string after splitting is", s.split(", "))

# Strips leading/trailing whitespace
s.strip()
print("the string after stripping is", s.strip())

# count the number of occurrences of a substring
s.count("l")
print("the number of occurrences of the substring is", s.count("l"))

# Checks if the string is alphanumeric
s.isalnum()
print("is the string alphanumeric?", s.isalnum())
the length of the string is 13
the string in uppercase is HELLO, WORLD!
the string in lowercase is hello, world!
the string with first letter capitalized is Hello, world!
the first occurrence of the substring is at 7
the string after replacement is Hello, Python!
the string after splitting is ['Hello', 'World!']
the string after stripping is Hello, World!
the number of occurrences of the substring is 3
is the string alphanumeric? False
  • split(): By default, .split() separates a string using any whitespace (spaces, tabs, newlines) and returns a list of words.
text = "  Hello   World  "  
text.split()
['Hello', 'World']
text_3 = "apple,banana,cherry"
text_3.split(",")
['apple', 'banana', 'cherry']
  • count(): Returns the number of non-overlapping occurences of a substring in a string. It is case-sensitive
text = "the three thieves thought they were thorough"

# Count how many times 'th' appears
print(text.count("th"))  

# Count how many times 'the' appears
print(text.count("the"))  
6
2

For word-level counting, use .split() or regular expressions

sentence = "The dog and the cat chased the rat."
sentence.lower().split().count("the") 
3
  • str.startswith() and str.endswith()
  • startswith() checks is a string begins with the specified substring.
text = "hello world"

print(text.startswith("hello"))   
print(text.startswith("world")) 
True
False
  • endswith(): Checks if a string ends with the specified substring.
text = "hello world"

print(text.endswith("world"))     # True
print(text.endswith("hello"))
True
False

3.3.3.2 Numerical Data Types

In Python, numerical data includes:

  • Integers (int): Whole numbers, positive or negative (e.g., -5, 0, 42)
  • Floats (float): Numbers with decimal points, used to represent real values (e.g., 3.14, -0.5, 2.0)

3.3.4 Common Mathematical Operators

Python provides several operators that can be used in expressions to perform mathematical calculations. Below are the most common ones:

  1. Exponentiation (**): Raises a number to the power of another.
    • Example: 2 ** 3 results in 8.
  2. Modulo (%): Returns the remainder of a division.
    • Example: 10 % 3 results in 1.
  3. Multiplication (*): Multiplies two numbers.
    • Example: 4 * 5 results in 20.
  4. Division (/): Divides one number by another, resulting in a float.
    • Example: 10 / 2 results in 5.0.
  5. Addition (+): Adds two numbers.
    • Example: 7 + 3 results in 10.
  6. Subtraction (-): Subtracts one number from another.
    • Example: 9 - 4 results in 5.

⚠️ Important:
When used with strings: - + joins strings together.
Example: "Hello" + "World""HelloWorld" - * repeats a string.
Example: "ha" * 3"hahaha"

These operations do not perform addition or multiplication in the mathematical sense when applied to strings.

3.3.5 Operator Precedence in Python

The operators listed above are in decreasing order of precedence, meaning:

  1. Exponentiation (**) is evaluated first.
  2. Modulo (%) is evaluated next.
  3. Multiplication (*) follows.
  4. Division (/), if present, has the same precedence as multiplication.
  5. Addition (+) and Subtraction (-) are evaluated last, from left to right.

3.3.5.1 Example: Precedence in Action

Consider the expression: 2 + 3 % 4 * 2

To evaluate this, Python follows the precedence rules:

  1. Modulo (%) is evaluated first:
3 % 4
3

Multiplication (*) is evaluated next:

3 * 2
6

Addition (+) is evaluated last:

2+6
8

Thus, the result of the expression 2 + 3 % 4 * 2 is 8.

3.3.5.2 Key Takeaways

  • Precedence determines the order in which operations are performed in an expression.
  • Parentheses () can be used to override the default precedence and control the order of evaluation.
result = (2 + 3) % (4 * 2)
print(result)
5

3.3.6 Practice exercise 4

What will be the result of the following expression:

1%2**3*2+1

The formula for computing final amount if one is earning compund interest is given by: \[A = P\bigg(1+\frac{r}{n}\bigg)^{nt},\]

where:
P = Principal amount (initial investment),
r = annual nominal interest rate,
n = number of times the interest is computed per year,
t = number of years

Write a Python program that assigns the principal amount of $10000 to variable P, assign to n the value 12, and assign to r the interest rate of 8%. Then have the program prompt the user for the number of years t that the money will be compounded for. Calculate and print the final amount after t years.

What is the amount if the user enters t as 4 years?

3.3.6.1 Booleans

Booleans represent logical values True or False.

They are commonly used to control the flow of a program through conditional statements such as if, elif, and while.

is_valid = True
if is_valid:
    print("The value is valid")
The value is valid

3.5 Expressions

An expression is any combination of values, variables, operators, and function calls that Python can evaluate (i.e., compute) to produce another value.

for example:

x = 4
y = 5

2 + 3         # ➝ 5 (an expression)
x * (y + 1)   # ➝ depends on x and y (still an expression)
24

💡 In short: An expression is something that evaluates to a value.

3.6 Converting data types in Python

3.6.1 Why Convert Data Types in Python?

Data type conversion is essential in Python for several reasons:

  • Compatibility: Some operations or functions require specific data types to work correctly.

    • Example: Performing arithmetic operations like addition or multiplication requires numeric types such as int or float. If the input is in another type, such as a string, it must be converted first.
# Example: Converting strings to numbers
price = "19.99"
tax = 0.07
total_price = float(price) * (1 + tax)  # Convert string to float
print(total_price)  # Output: 21.3893
21.3893
  • Data Processing: When working with input data (e.g., user input, etc), the data may need to be converted to the appropriate type for further analysis.

Example: Converting strings to numbers to perform calculations

# Example: Arithmetic requires numeric types
num_str = "42"
result = int(num_str) + 10  # Converts the string "42" to integer
print(result)  # Output: 52
52
  • Error Prevention: Converting data types ensures consistency and prevents runtime errors caused by type mismatches.
# Example: Avoiding type mismatch errors
age = 25
message = "Your age is " + str(age)  # Convert integer to string for concatenation
print(message)  # Output: "Your age is 25"
Your age is 25

3.6.2 How to Convert Data Types in Python

Python provides several built-in functions for type conversion.

Common Conversion Functions:

Function Description Example
int() Converts to an integer (from float or string) int("42")42
float() Converts to a float float("3.14")3.14
str() Converts to a string str(42)"42"
bool() Converts to a boolean bool(1)True

3.6.3 Boolean conversion

In Python, you can convert values to True or False using the built-in bool() function.

The conversion follows these general rules:

  • Falsy values (converted to False):
    • None
    • False
    • 0, 0.0
    • '' (empty string)
    • [] (empty list), {} (empty dict), set(), etc.
  • Truthy values (converted to True):
    Anything not falsy, like:
    • Non-zero numbers: 1, -5, 3.14
    • Non-empty strings: "hello"
    • Non-empty collections: [1], {'a': 1}, etc.
print(bool(0))       # Output: False
print(bool(""))      # Output: False
print(bool("hello")) # Output: True
print(bool([1, 2]))  # Output: True
False
False
True
True

3.6.4 Converting between numeric types

You can convert between integers and floating-point numbers. When converting from an integer to a float, Python implicitly adds the decimal point (.0). When converting from a float to an integer, Python truncates the decimal portion (removes the digits after the decimal point).

# Integer to float
x = 42
y = float(x)  # Converts int to float
print(y)  # Output: 42.0

# Float to integer (truncating the decimal part)
x = 42.99
y = int(x)  # Converts float to int (truncating the decimal part)
print(y)  # Output: 42
42.0
42

3.7 User input

Python’s built-in input() function is used to take input from the user during program execution. It reads a line of text entered by the user and returns it as a string.

name = input("What is your name? ")
print(f"Hello, {name}!")
Hello, lizhen!

3.7.0.1 🔤 Important:

  • The input() is always returned as a string, even if the user enters a number.
  • You can convert the input to other types (e.g., int, float) using type conversion functions.
  • The program execution pauses until the user provides input.

Examples

# To take numeric input, you need to convert the string to an appropriate data type:
age = int(input("Enter your age: "))
print(f"You will be {age + 1} years old next year.")
# input for calculating the area of a circle
radius = float(input("Enter the radius of the circle: "))
area = 3.14 * radius ** 2
print(f"The area of the circle is {area}")

3.7.1 Practice exercise 6

Ask the user to input their year of birth, and print their age.

3.8 Errors and Exceptions

Errors and Exceptions are common while writing and executing Python code.

3.8.1 Syntax errors

Syntax errors occur if the code is written in a way that it does not comply with the rules / standards / laws of the language (python in this case). It occur when the Python parser encounters invalid syntax.

For example, suppose a values is assigned to a variable as follows:

9value = 2

The above code when executed will indicate a syntax error as it violates the rule that a variable name must not start with a number.

# another example
print("Hello World"

Solution: Fix the syntax issue by ensuring correct punctuation or structure.

3.8.2 Exceptions

Even if a statement or expression is syntactically correct, it may cause an error when an attempt is made to execute it. Errors detected during execution are called exceptions and are not unconditionally fatal:

Exceptions come in different types, and the type is printed as part of the message: below are the common ones:

  • Using a local or global variables that is not defined prior
  • Attempts to perform operations (such as math operations) on data of the wrong type (ex. attempting to subtract two variables that hold string values)
  • Dividing by zero
  • Attempts to use a type conversion function such as int on a value that can’t be converted to an int

For example, suppose a number is multipled as follws:

multiplication_result = misy * 4
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[29], line 1
----> 1 multiplication_result = misy * 4

NameError: name 'misy' is not defined

The above code is syntactically correct. However, it will generate an error as the variable misy has not been defined as a number.

# Raised when a function receives an argument of the right type but inappropriate value.
int("abc")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[25], line 1
----> 1 int("abc")

ValueError: invalid literal for int() with base 10: 'abc'
# raised when an operation is applied to an object of inappropriate type.
int("hello")
print("2" + 3)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[24], line 1
----> 1 print("2" + 3)

TypeError: can only concatenate str (not "int") to str
# zero division error
# raised when the second argument of a division or modulo operation is zero.

print(10 / 0)
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
Cell In[27], line 1
----> 1 print(10 / 0)

ZeroDivisionError: division by zero

3.8.3 Exception Handling

When an error occurs, or exception as we call it, Python will normally stop and generate an error message.

If we suspect that some lines of code may produce an error, we can put them in a try block, and if an error does occur, we can use the except block to instead execute an alternative piece of code. This way the program will not stop if an error occurs within the try block, and instead will be directed to execute the code within the except block.

These exceptions can be handled Using the Try-Except Blocks


try:
    print(10 / 0)
except:
    print("Cannot divide by zero!")
Cannot divide by zero!

Since the try block raises an error, the except block will be executed. Without the try block, the program will crash and raise an error:

The finally block, if specified, will be executed regardless if the try block raises an error or not.

try:
    print(10 / 0)
except:
    print("Cannot divide by zero!")
finally:
    print("This will always execute.")
Cannot divide by zero!
This will always execute.

3.8.4 Practice exercise 7

Suppose we wish to compute tax using the income and the tax rate. Identify the type of error from amongst syntax error, semantic error and run-time error in the following pieces of code.

income = 2000
tax = .08 * Income
print("tax on", income, "is:", tax)
income = 2000
tax = .08 x income
print("tax on", income, "is:", tax)
  Cell In[1], line 2
    tax = .08 x income
              ^
SyntaxError: invalid syntax
income = 2000
tax = .08 ** income
print("tax on", income, "is:", tax)
tax on 2000 is: 0.0

3.8.5 Practice exercise 8

Input an integer from the user. If the user inputs a valid integer, print whether it is a multiple of 3. However, if the user does not input a valid integer, print a message saying that the input is invalid.

num = input("Enter an integer:")

#The code lines within the 'try' block will execute as long as they run without error  
try:
    #Converting the input to integer, as user input is a string
    num_int = int(num)  
    
    #checking if the integer is a multiple of 3
    if num_int % 3 == 0:            
        print("Number is a multiple of 3")
    else:
        print("Number is not a multiple of 3")
        
#The code lines within the 'except' block will execute only if the code lines within the 'try' block throw an error        
except:
    print("Input must be an integer")
Input must be an integer

3.8.6 Semantic errors (bugs)

Semantic errors occur when the code executes without an error being indicated by the compiler. However, it does not work as inteded by the user. For example, consider the following code of mutiplying the number 6 by 3:

x = '6'
x * 3
'666'

If it was intended to multiply the number 6, then the variable x should have been defined as x=6 so that x has a value of type integer. However, in the above code 6 is a string type value. When a string is multiplied by an integer, say n, it concatenates with itself n times.