Lecture 2 — Variables, Types, and Assignment#

Lecture 2 of 18 — Progress: 11%

PyPro-SCiDaS

An Initiation to Programming using Python (Init2Py)

📦 Lecture 2 — Variables, Types, and Assignment

Python Proficiency for Scientific Computing and Data Science

🧑‍🏫 Instructor: Yaé Gaba 📘 Course: Init2Py 📅 Date: October 2025 🎓 Semester: Semester 1, 2025–2026 ⏱️ Estimated: 60 min Beginner
🏛️ AI Research and Innovation Nexus for Africa (AIRINA Labs), AI.Technipreneurs, Bénin
& African Center for Advanced Studies (ACAS), Cameroon
✉️ yaeulrich.gaba@gmail.com   |   🔗 LinkedIn | 🌐 Website

🎯 Learning Objectives

By the end of this lecture, you will be able to:

  • ✅ Create and name variables using Python's naming conventions
  • ✅ Understand dynamic typing and type checking with type()
  • ✅ Work with numeric types: int, float, complex, bool
  • ✅ Perform type conversions (casting) between types
  • ✅ Use assignment operators and multiple assignment
With a solid understanding of types, let's look at the operators that let us compute and compare values.

📝 Practice Exercises

  1. Type detective: Create variables of 6 different types (int, float, str, bool, complex, NoneType). Use type() to verify each one.
  2. Parallel swap: Given a = 10 and b = 20, swap their values using parallel assignment (one line, no temporary variable).
  3. Type casting chain: Start with the string "3.14". Convert it to float, then to int, then back to str. Print the result at each step.
  4. User calculator: Use input() to ask the user for two numbers. Print their sum, difference, product, and quotient.
  5. Naming quiz: Which of these are valid Python variable names? my_var, 2nd_place, class, _private, my-var. Explain why each is valid or invalid.
# Exercise 1: Create 6 variables of different types


# Exercise 2: Swap a and b
a = 10
b = 20
# Your code here


# Exercise 3: Type casting chain
x = "3.14"
# Your code here


# Exercise 4: User calculator
# Your code here
Click to show solution
# Exercise 1: Create 6 variables of different types
my_int = 42
my_float = 3.14
my_str = "hello"
my_bool = True
my_complex = 2 + 3j
my_none = None

print(type(my_int))      # <class 'int'>
print(type(my_float))    # <class 'float'>
print(type(my_str))      # <class 'str'>
print(type(my_bool))     # <class 'bool'>
print(type(my_complex))  # <class 'complex'>
print(type(my_none))     # <class 'NoneType'>


# Exercise 2: Swap a and b
a = 10
b = 20
a, b = b, a
print(f"a = {a}, b = {b}")  # a = 20, b = 10


# Exercise 3: Type casting chain
x = "3.14"
print(f"String: {x}, type: {type(x)}")

x_float = float(x)
print(f"Float:  {x_float}, type: {type(x_float)}")

x_int = int(x_float)
print(f"Int:    {x_int}, type: {type(x_int)}")

x_str = str(x_int)
print(f"String: {x_str}, type: {type(x_str)}")


# Exercise 4: User calculator
num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))

print(f"Sum:        {num1 + num2}")
print(f"Difference: {num1 - num2}")
print(f"Product:    {num1 * num2}")
print(f"Quotient:   {num1 / num2}")

🔗 Building on What You Know

In Lecture 1, you got your first taste of Python: running code in Jupyter, printing output, and seeing different data types in action. Now let's go deeper into the building blocks — understanding exactly how Python stores, names, and converts data through variables and types.

🌍 Real-World Scenario

Imagine you are a climate researcher. You receive a dataset with temperature readings: some are integers (23), some are floats (23.7), some are strings ("missing"), and some are boolean flags (True for validated). Before you can analyze anything, you need to understand what type each piece of data is, how to convert between types, and how Python stores them in variables.

This lecture gives you the foundation: how Python handles data — from naming variables to understanding types, casting, and operators.


🧾 Summary

This lecture explores variables, types, and assignments in Python. We'll learn that Python uses object references rather than traditional variables, and discover how assignment works differently with mutable vs immutable objects. Understanding these concepts is crucial for effective Python programming and avoiding common pitfalls.

---

🔗 Key Concepts

  • 📝 Variable Assignment: The = operator and naming conventions
  • 🔗 Object References: How Python handles variable assignment internally
  • 🏷️ Naming Rules: Valid identifiers and Python naming conventions

🔗 Resources


Let's dive into Python variables and master the fundamentals of types! 🚀

🎯 Introduction to Python Variables

In Python, a variable is a fundamental programming construct that facilitates the storage and management of information in the computer's memory. It is assigned a symbolic name, which serves as a reference to the data stored at a particular location in memory.

🧠 Key Insight: Variables in Python act as references to objects in memory rather than containing the data themselves. This reference-based approach allows for efficient memory management and dynamic data interaction.

Python's dynamic typing system means variables can be reassigned to different data types during execution. Combined with automatic garbage collection, this provides both flexibility and optimized performance.

Defined with the assignment operator = • Flexible assignment • Efficient memory management

🔰 Defining Variables in Python

Python provides four fundamental ways to define variables, each suited to different programming scenarios and requirements.

🎯
Direct Assignment

Assign a variable with a specific value directly. Ideal for initializing variables with known values.

x = 10
🔄
Multiple Assignment

Assign the same value to multiple variables simultaneously. Efficient for bulk initialization.

x = y = z = 0
Parallel Assignment

Define multiple variables in one statement with different values. Perfect for concise initialization.

x, y, z = 1, 2, 3
🧮
Expression Assignment

Create variables from expressions involving other variables. Enables calculations and transformations.

result = x + y * 2
💡 Each method provides unique flexibility for different variable definition scenarios

🎯 Direct Assignment

The most straightforward method where a variable is assigned a specific value directly using the = operator. This code snippet illustrates the process of creating variables in Python by assigning them specific values. The variable y is assigned a floating-point number, while the variable salutation is assigned a string value.

y = 4.8134 # Defines a variable named y with value 4.8134
salutation = "How are you ?" # Defines salutation with string value

💫 This assignment operation creates a reference between the variable name and the data, allowing you to reuse and manipulate the data through the variable name throughout your code.

Variable names
Numeric values
String values
y = 4.8134  # Defines a variable named y and assigns it the value 4.8134
salutation = "How are you?"  # Defines a variable named salutation and assigns it the value "How are you?"
x = 56


📤 Displaying Variables with print()

To display the values of defined variables, we use the print() function—a built-in Python function for outputting data to the console.

print(y) # Output: 4.8134
print(salutation) # Output: How are you ?
print(y, salutation) # Output: 4.8134 How are you ?

🚀 The print() function can take multiple arguments, allowing you to print several variables at once. It automatically converts them to their string representation, making it essential for debugging and monitoring variable states.

Function name
Variables
Output comments
---
print(x)
print(y)
print(salutation)
56
4.8134
How are you?


📝 Single-Line Output with print()

Display multiple values on the same line using a single print() function, separating variables with commas.

print(y, salutation, z) # Output: 4.8134 How are you ? 42
# Commas automatically insert spaces between values
🎯

Automatic Formatting: The commas in print() automatically insert spaces between values, creating readable output without manual formatting.

Efficient Output: Output multiple pieces of data in a single line without needing to concatenate strings or add spaces manually.

🚫
Manual concatenation
Automatic spacing
# Display the result
print(x,y,salutation)
56 4.8134 How are you?


🔄 Multiple Assignment

A multiple assignment is a specific case of direct assignment where the same value is assigned to multiple variables in a single line of code.

x = y = 7 # x and y are both assigned the value 7 simultaneously

💡 This technique is useful when you need to initialize several variables with the same starting value efficiently, keeping your code concise and readable while ensuring consistency across your code.

🎯 Efficient initialization
📝 Concise code
🔒 Consistent values
---
x = y = 7  # x and y are both assigned the value 7 simultaneously.
print(x)
print("=======================")
print(y)
7
=======================
7

Parallel Assignment

A parallel assignment involves defining multiple variables using a single equals sign, allowing you to assign different values to several variables simultaneously.

x, y = 4, 8.33 # Defines x with 4 and y with 8.33 simultaneously

🚀 This approach enhances code readability and efficiency, especially when you need to initialize multiple variables at once. It's particularly useful for initializing or updating several variables in a concise and organized manner.

🎯 Simultaneous assignment
📖 Readable code
💫 Efficient initialization
x, y = 4, 8.33   # Defines two variables, x and y, with values 4 and 8.33 respectively.
# Display the result
print(x,y)
4 8.33
x, y , z= 4, 8.33, 65  # Defines two variables, x and y, with values 4 and 8.33 respectively.
print(x,y,z)
4 8.33 65

🧮 Assignment from Expressions

Variables can be defined based on expressions involving other variables. This allows you to create new variables that represent calculations, transformations, or combinations of existing data.

z1 = x + y # z1 stores the sum of x and y
z2 = x + 5 # z2 stores x plus 5
z3 = 2 * y # z3 stores twice the value of y
print(z1, z2, z3) # Display all calculated values

💡 This method demonstrates how Python variables can dynamically interact with each other. When you use variables in expressions, Python uses their current values to compute the result, creating powerful relationships between different pieces of data in your program.

Arithmetic operations
🔄 Dynamic relationships
🎯 Calculated values
#Define a variable based on other variables
z1 = x + y  # Defines the variable named z1 and assigns it the sum of variables x and y
z2 = x + 5  # Defines the variable named z2 by adding 5 to the value of x
z3 = 2 * y  # Defines the variable named z3 by multiplying the value of y by 2

print(z1,z2,z3)
60.8134 61 9.6268
⚠️ Assignment is NOT Comparison!

It's crucial to understand that the assignment operator = in programming does not have the same meaning as the equality symbol = in mathematics.

➡️
Assignment Operator
x = 5
Stores value 5 in variable x
🔄
Equality Operator
x == 5
Checks if x equals 5

🚫 Key difference: The assignment operator is not symmetric! Attempting to swap the order (5 = x) will cause an error, while mathematical equality is symmetric (if x=5 then 5=x).

5 = x → Error!
x = 5 → Correct
x == 5 → Comparison
# Error
128 = a
  Cell In[4], line 2
    128 = a
    ^
SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='?
🏷️ Python Variable Naming Conventions

Choosing appropriate variable names is crucial for writing readable and maintainable code. Python has specific rules and conventions for naming variables.

📝 Naming Rules

  • 🚫 Reserved keywords like if, else cannot be used as variable names
  • ✅ Can start with _, letter, or $
  • ✅ Can use lowercase or uppercase letters
  • 🚫 Cannot start with a digit
  • 🚫 No white spaces allowed

💡 A good programmer naturally strives to choose the most meaningful variable names possible.

🔑 Python's 33 Reserved Keywords

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

🐍 Using the Keyword Module

import keyword # Import the keyword module
print(keyword.kwlist) # Get all reserved keywords
print(keyword.iskeyword('if')) # Returns True
print(keyword.iskeyword('my_var')) # Returns False
import keyword
print(keyword.kwlist)
print(keyword.iskeyword('if'))  # Returns True
print(keyword.iskeyword('my_var'))  # Returns False
🔤 Python Naming Conventions & Case Sensitivity

⚠️ Important: Python is case-sensitive, so variable names Age and age are considered distinct variables.

📏 Recommended Naming Conventions

🏛️ UpperCamelCase

For class names

class BankAccount:
🌟 CAPITALIZED_WITH_UNDERSCORES

For constants

MAX_CONNECTIONS = 100
🐍 snake_case

For variables, functions, and methods

user_age = 25
🔍 Age ≠ age
📚 Follow conventions
🎯 Readable code
🔄 Swapping Variable Values - Three Methods

Let's assume variables x and y have values α and β respectively. Explore three different approaches to swap their contents.

📦 Method 1: Using Temporary Variable

tmp = x
x = y
y = tmp

Uses an auxiliary variable tmp to temporarily store one value during the swap.

🧮 Method 2: Mathematical Approach

x = x + y
y = x - y
x = x - y

Uses arithmetic operations to swap values without a temporary variable. Works only with numeric types.

🐍 Method 3: Pythonic Parallel Assignment

x, y = y, x

The most elegant and Pythonic approach. Works with any data type and is both readable and efficient.

💻 Live Example

# Method 1 - Temporary Variable
x = 5; y = 4
tmp = x; x = y; y = tmp
print(x, y) # Output: 4 5
# Method 3 - Pythonic (Recommended)
x = 90; y = 15
x, y = y, x
print(x, y) # Output: 15 90
📦 Universal (Method 1)
🧮 Mathematical (Method 2)
Pythonic (Method 3)

🗑️ Deleting Variables with `del`

To delete a variable in Python, you can use the del statement. This removes the variable from the current namespace, effectively deleting it and freeing up resources.

x = 10 # Define a variable x
print(x) # Output: 10
del x # Delete the variable x
print(x) # NameError: name 'x' is not defined

⚠️ After executing del x, the variable x will no longer exist in the current scope. Attempting to access it will result in a NameError.

Before del
x = 10
Variable exists
After del
del x
NameError occurs
🔥 Removes variable
💾 Frees memory
🚫 Causes NameError
---
x = 10  # Define a variable x
print(x)

del x   # Delete the variable x
print(x)
10
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[5], line 5
      2 print(x)
      4 del x   # Delete the variable x
----> 5 print(x)

NameError: name 'x' is not defined
You may have noticed that we never declared a variable's type. That's because Python uses dynamic typing — let's understand what that means.

🔍 Variable Types in Python

In Python, the type of a variable refers to the kind of data it holds, such as integers, floating-point numbers, strings, or more complex data structures. Python dynamically assigns types based on values, and you can check any variable's type using the type() function. The type of a variable corresponds to its nature. There are many types of variables (integer, real number, strings, etc.). The most commonly encountered types of variables are integers int, real numbers float, and strings str. The basic types include:

📊 Basic Data Types

🚫 None
Represents nothing or no value
📝 str String
'Calvin'
"Calvin'n'Hobbes"
str(3.2) → "3.2"
🔘 bool Boolean
True   False

🔢 Numeric Types

int -2, 0, 42
int(2.1) → 2   •   int("4") → 4
float 3.14, -2.5, 0.0
complex 1+2j, 5.1j
complex(-3.14)   •   complex('j')

🔄 Iterable Types

list ['a', 3, [1, 2], 'a']
tuple (2, 3.1, 'a', [])
dict {'a':1, 'b':[1, 2], 3:'c'}
set {1, 2, 3, 2}

🐍 Using the type() Function

x = 42
print(type(x)) # Output: <class 'int'>
y = "Hello"
print(type(y)) # Output: <class 'str'>
🎭
Dynamic Typing
🔍
type() Function
📚
Rich Type System
---

2.0. None (nothing)#

The None type represents the absence of a value or a null value in Python. It is often used to signify that a variable has no value assigned to it or to indicate the end of a list, function, or loop.

Example:

x = None
x = None
print(x, type(x))

2.1. String Types (str)#

Strings in Python are sequences of characters enclosed in quotes. They can be defined using single ('), double ("), or triple quotes (''' or """). Triple quotes allow for multi-line strings.

Examples:

name = 'Calvin'
quote = "Calvin'n'Hobbes"
multi_line = '''Two
lines'''
name = 'Calvin'
quote = "Calvin'n'Hobbes"
multi_line = '''Two
lines'''
# Display the result
print(name)
Calvin
# Display the result
print(quote)
Calvin'n'Hobbes
# Display the result
print(multi_line)
Two
lines
# Check the variable type
type(name)
str
name = 'Calvin'
quote = "Calvin'n'Hobbes"
multi_line = '''Two
lines'''

print(name, type(name), '\n')
print('====================================')

print(quote, type(quote),'\n')
print('====================================')


print(multi_line, type(multi_line))
print('====================================')
Calvin <class 'str'> 

====================================
Calvin'n'Hobbes <class 'str'> 

====================================
Two
lines <class 'str'>
====================================
Now that we understand how strings work as text data, let's explore the numeric types that let Python handle mathematical computations.

2.2. Numeric Types#

2.2.0. Booleans (bool)#

Booleans represent one of two values: True or False. They are often used in conditional statements to determine the flow of a program.

Examples:

is_active = True
has_permission = False
is_active = True
has_permission = False


print(is_active, type(is_active), '\n')
print('====================================')

print(has_permission, type(has_permission), '\n')

2.2.1. Integers (int)#

Integers are whole numbers without a fractional component. In Python, integers can be of arbitrary precision, meaning they can be as large as the memory allows.

Examples:

age = 25
negative_number = -42
a, b = 'hi', 4
age = 25
negative_number = -42

print(age, type(age), '\n')
print('====================================')
print(negative_number, type(negative_number))

2.2.2. Reals (float)#

Floating-point numbers (floats) are numbers with a decimal point. They are used to represent real numbers in Python.

Examples:

pi = 3.14159
temperature = -2.5
pi = 3.14159
temperature = -2.5


print(pi, type(pi), '\n')
print('====================================')
print(temperature, type(temperature))

2.2.3. Complex (complex)#

Complex numbers in Python consist of a real part and an imaginary part. They are represented by a + bj, where a is the real part and b is the imaginary part.

Examples:

z = 1 + 2j
w = complex(3, -4)
z = 1 + 2j
w = complex(3, -4)

print(z, type(z))
print('====================================')
print(w, type(w))
(1+2j) <class 'complex'>
====================================
(3-4j) <class 'complex'>
Beyond single values, Python provides container types that can hold multiple items. Let's explore these iterable objects.

2.3. Iterable Objects#

2.3.0. Lists (list)#

A list is an ordered collection of items that can be of different types. Lists are mutable, meaning their contents can be changed after creation.

Examples:

fruits = ['apple', 'banana', 'cherry']
mixed = [1, 'two', 3.0, [4, 5]]
fruits = ['apple', 'banana', 'cherry']
mixed = [1, 'two', 3.0, [4, 5]]


print(fruits, type(fruits))
print('====================================')
print(mixed, type(mixed))

2.3.1. Immutable Lists (tuple)#

A tuple is similar to a list but is immutable, meaning its contents cannot be changed after creation. Tuples are often used to store collections of related data.

Examples:

coordinates = (10.5, 20.8)
colors = ('red', 'green', 'blue')
coordinates = (10.5, 20.8)
colors = ('red', 'green', 'blue')

print(coordinates, type(coordinates))
print('====================================')
print(colors, type(colors))

2.3.2. Keyed Lists (dict)#

A dictionary is a collection of key-value pairs, where each key is associated with a value. Dictionaries are mutable and allow for fast lookup of values based on their keys.

Examples:

person = {'name': 'Alice', 'age': 30}
inventory = {'apples': 10, 'bananas': 20}
person = {'name': 'Alice', 'age': 30}
inventory = {'apples': 10, 'bananas': 20}


print(person, type(person))
print('====================================')
print(inventory, type(inventory))

2.3.3. Unordered Sets of Unique Elements (set)#

A set is an unordered collection of unique elements. Sets are useful for membership tests and eliminating duplicate entries.

Examples:

unique_numbers = {1, 2, 3, 2}
letters = {'a', 'b', 'c', 'a'}
unique_numbers = {1, 2, 3, 2}
letters = {'a', 'b', 'c', 'a'}

print(unique_numbers, type(unique_numbers))
print('====================================')
print(letters , type(letters ))

2.4. Dynamic Typing in Python#

Python is a dynamically typed language, meaning that the type of a variable is determined at runtime rather than at compile time. In Python, you don’t need to declare the type of a variable when you create it. Instead, the type is inferred based on the value assigned to the variable. This allows for more flexibility but also requires careful handling to avoid type-related errors.

Key Characteristics of Dynamic Typing:#

  • No Type Declaration: You simply assign a value to a variable, and Python automatically knows what type it is.

    x = 10        # x is an integer
    x = "hello"   # Now, x is a string
    
  • Type Flexibility: The type of a variable can change over its lifetime. You can reassign a variable to a value of a different type without any issues.

    y = 3.14      # y is initially a float
    y = True      # Now, y is a boolean
    
  • Memory Management: Python handles memory management automatically. When you reassign a variable to a new value, the previous value is discarded if it’s no longer referenced elsewhere in the code.

Pros and Cons of Dynamic Typing:#

  • Pros:

    • Flexibility: You can write more general-purpose code since the type is not fixed.

    • Ease of Use: Less boilerplate code, as there is no need for explicit type declarations.

  • Cons:

    • Type-Related Errors: Since types are determined at runtime, it’s possible to encounter errors if the wrong type is used in an operation.

    • Performance: Dynamic typing can be slower than static typing because type checks are done at runtime.

Example:#

# Initially, 'data' is an integer
data = 100

# Now, 'data' is a string
data = "Dynamic Typing"

# And now 'data' is a list
data = [1, 2, 3]

# Python handles these changes without any issues
data = 100
type(data)
int
data = 'Kigali'
type(data)
str
Since Python determines types at runtime, what happens when you mix types in an expression? This is where coercion comes in.

2.5. Coercion in Python#

Coercion in Python refers to the automatic conversion of one data type to another during operations that involve different types. Python is designed to handle these type conversions in a way that makes the language easier to use and reduces the need for manual type casting.

Key Points About Coercion:#

  • Implicit Coercion: Python automatically converts one data type to another when necessary to perform an operation. This usually happens in arithmetic operations involving different types, like an integer and a float.

    • For example, if you add an integer to a float, Python will convert the integer to a float before performing the addition.

  • Explicit Coercion: While Python handles many conversions automatically, you can also manually convert types using built-in functions like int(), float(), str(), etc. This is known as explicit type casting.

2.5. 0. Implicit Coercion Example:#

# Adding an integer and a float
x = 5        # int
y = 3.2      # float

# Python automatically converts 'x' to a float before performing the addition
result = x + y

print(result)  # Output: 8.2 (float)

In the example above, Python automatically converts the integer 5 to a float 5.0 to perform the addition with the float 3.2, resulting in a float 8.2.

x = 5        # int
y = 3.2      # float

type(x+y)
float
3 == 3.0
True
# Adding an integer and a float
x = 5        # int
y = 3.2      # float

# Python automatically converts 'x' to a float before performing the addition
result = x + y




print(x, type(x), '\n')
print('====================================')
print(y, type(y),'\n')
print('====================================')
print(result, type(result))  # Output: 8.2 (float)

2.5.1. Explicit Coercion Example:#

# Converting a float to an integer
a = 7.9
b = int(a)  # Explicit coercion using the int() function

print(b)  # Output: 7 (integer, with the decimal part truncated)

Here, the float 7.9 is explicitly converted to the integer 7 using the int() function, which removes the fractional part.

a = 7.9
b = int(a)  # Explicit coercion using the int() function

print(b)  # Output: 7 (integer, with the decimal part truncated)
7
c = str(a)
print(a)
print(type(a))
print(c)
type(c)
7.9
<class 'float'>
7.9
str
# Display the result
print(c)
7.9

2.5.2. Common Coercion Scenarios:#

  • String to Integer/Float: When you need to convert a string containing numeric characters to an integer or float.

    num_str = "123"
    num_int = int(num_str)   # Converts to integer 123
    num_float = float(num_str)  # Converts to float 123.0
    
  • Integer/Float to String: When you need to concatenate a number with a string.

    age = 25
    message = "I am " + str(age) + " years old."
    
  • Boolean to Integer: True is coerced to 1 and False to 0 in numeric operations.

    result = True + 2   # Output: 3 (1 + 2)
    

2.5.3. Pros and Cons of Coercion:#

  • Pros:

    • Simplifies code by reducing the need for explicit type conversions.

    • Makes the language more intuitive and user-friendly.

  • Cons:

    • Can lead to unexpected results if the automatic type conversion doesn’t align with the programmer’s intent.

    • Potentially hides bugs related to incorrect data types.

Coercion in Python allows for smoother and more intuitive operations involving different data types. While it adds convenience, it’s important to understand how and when Python performs these conversions to avoid unexpected behaviors.

age = 25
message = "I am " + str(age) + " years old."
print(message)
type(message)
I am 25 years old.
str

3. Methods associated with variables#

In Python, every variable is linked to a variety of attributes and methods that define its behavior and interactions. These methods are functions that are built into the variable’s type and allow you to perform various operations on the variable. For example, methods can help you manipulate strings, perform mathematical operations, or interact with lists and dictionaries.

The dir() function is useful for exploring these methods and understanding what operations are available for a given variable. By calling dir() on a variable, you get a list of all its attributes and methods, including those inherited from its type. This can be particularly helpful for discovering how to use a variable’s methods or for debugging.

Here’s how you might use dir():

# Example with a string variable
text = "Hello, world!"
print(dir(text))

# Example with a list variable
numbers = [1, 2, 3, 4, 5]
print(dir(numbers))

In the examples above, dir(text) will list methods related to string operations such as upper(), lower(), and split(), while dir(numbers) will show methods related to list operations like append(), remove(), and sort(). This feature of Python makes it easier to explore and utilize the functionalities associated with different data types.

x = 2.5 # Define a numeric variable x
y = 'my text' # Define a string variable y.

To display all the methods associated with each of these variables, we do:

# Display the result
print(dir(x))
['__abs__', '__add__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getformat__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__int__', '__le__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__pos__', '__pow__', '__radd__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmod__', '__rmul__', '__round__', '__rpow__', '__rsub__', '__rtruediv__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', 'as_integer_ratio', 'conjugate', 'fromhex', 'hex', 'imag', 'is_integer', 'real']
x.real
2.5
# Display the result
print(dir(y))

You can also type variable_name. followed by TAB in many interactive Python environments or integrated development environments (IDEs). This action triggers autocompletion, which helps you see and select available methods and attributes associated with that variable. For example:

  1. Type variable_name. and press TAB.

  2. A list of methods and attributes that can be used with variable_name will appear.

This feature is especially useful for exploring what operations you can perform on a variable and for quickly finding the right method without needing to remember exact method names.

# Type x. followed by `TAB`

To get help on a specific method in Python, you can use the help() function. The syntax is help(variable_name.method_name), where method_name is the name of the method you are interested in. For example, if you have a numeric variable of type float, which includes a method named conjugate, you can obtain information about this method by running:

print(help(x.conjugate))

This will display documentation about the conjugate method, including its purpose and usage, in the console or terminal.

x = 2.5 # Define a numeric variable x
# Display the result
print(help(x.conjugate))
Help on built-in function conjugate:

conjugate() method of builtins.float instance
    Return self, the complex conjugate of any float.

None

To display help on all the functions associated with a variable x, you simply use:

help(x)

This command will show the documentation for the type of the variable x, including all the methods and attributes available for that type.

# Display the result
print(help(x))
Help on float object:

class float(object)
 |  float(x=0, /)
 |
 |  Convert a string or number to a floating-point number, if possible.
 |
 |  Methods defined here:
 |
 |  __abs__(self, /)
 |      abs(self)
 |
 |  __add__(self, value, /)
 |      Return self+value.
 |
 |  __bool__(self, /)
 |      True if self else False
 |
 |  __ceil__(self, /)
 |      Return the ceiling as an Integral.
 |
 |  __divmod__(self, value, /)
 |      Return divmod(self, value).
 |
 |  __eq__(self, value, /)
 |      Return self==value.
 |
 |  __float__(self, /)
 |      float(self)
 |
 |  __floor__(self, /)
 |      Return the floor as an Integral.
 |
 |  __floordiv__(self, value, /)
 |      Return self//value.
 |
 |  __format__(self, format_spec, /)
 |      Formats the float according to format_spec.
 |
 |  __ge__(self, value, /)
 |      Return self>=value.
 |
 |  __getnewargs__(self, /)
 |
 |  __gt__(self, value, /)
 |      Return self>value.
 |
 |  __hash__(self, /)
 |      Return hash(self).
 |
 |  __int__(self, /)
 |      int(self)
 |
 |  __le__(self, value, /)
 |      Return self<=value.
 |
 |  __lt__(self, value, /)
 |      Return self<value.
 |
 |  __mod__(self, value, /)
 |      Return self%value.
 |
 |  __mul__(self, value, /)
 |      Return self*value.
 |
 |  __ne__(self, value, /)
 |      Return self!=value.
 |
 |  __neg__(self, /)
 |      -self
 |
 |  __pos__(self, /)
 |      +self
 |
 |  __pow__(self, value, mod=None, /)
 |      Return pow(self, value, mod).
 |
 |  __radd__(self, value, /)
 |      Return value+self.
 |
 |  __rdivmod__(self, value, /)
 |      Return divmod(value, self).
 |
 |  __repr__(self, /)
 |      Return repr(self).
 |
 |  __rfloordiv__(self, value, /)
 |      Return value//self.
 |
 |  __rmod__(self, value, /)
 |      Return value%self.
 |
 |  __rmul__(self, value, /)
 |      Return value*self.
 |
 |  __round__(self, ndigits=None, /)
 |      Return the Integral closest to x, rounding half toward even.
 |
 |      When an argument is passed, work like built-in round(x, ndigits).
 |
 |  __rpow__(self, value, mod=None, /)
 |      Return pow(value, self, mod).
 |
 |  __rsub__(self, value, /)
 |      Return value-self.
 |
 |  __rtruediv__(self, value, /)
 |      Return value/self.
 |
 |  __sub__(self, value, /)
 |      Return self-value.
 |
 |  __truediv__(self, value, /)
 |      Return self/value.
 |
 |  __trunc__(self, /)
 |      Return the Integral closest to x between 0 and x.
 |
 |  as_integer_ratio(self, /)
 |      Return a pair of integers, whose ratio is exactly equal to the original float.
 |
 |      The ratio is in lowest terms and has a positive denominator.  Raise
 |      OverflowError on infinities and a ValueError on NaNs.
 |
 |      >>> (10.0).as_integer_ratio()
 |      (10, 1)
 |      >>> (0.0).as_integer_ratio()
 |      (0, 1)
 |      >>> (-.25).as_integer_ratio()
 |      (-1, 4)
 |
 |  conjugate(self, /)
 |      Return self, the complex conjugate of any float.
 |
 |  hex(self, /)
 |      Return a hexadecimal representation of a floating-point number.
 |
 |      >>> (-0.1).hex()
 |      '-0x1.999999999999ap-4'
 |      >>> 3.14159.hex()
 |      '0x1.921f9f01b866ep+1'
 |
 |  is_integer(self, /)
 |      Return True if the float is an integer.
 |
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |
 |  __getformat__(typestr, /)
 |      You probably don't want to use this function.
 |
 |        typestr
 |          Must be 'double' or 'float'.
 |
 |      It exists mainly to be used in Python's test suite.
 |
 |      This function returns whichever of 'unknown', 'IEEE, big-endian' or 'IEEE,
 |      little-endian' best describes the format of floating-point numbers used by the
 |      C type named by typestr.
 |
 |  fromhex(string, /)
 |      Create a floating-point number from a hexadecimal string.
 |
 |      >>> float.fromhex('0x1.ffffp10')
 |      2047.984375
 |      >>> float.fromhex('-0x1p-1074')
 |      -5e-324
 |
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |
 |  __new__(*args, **kwargs)
 |      Create and return a new object.  See help(type) for accurate signature.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  imag
 |      the imaginary part of a complex number
 |
 |  real
 |      the real part of a complex number

None

4. Arithmetic and Logical (Boolean) Operators#

In Python, two major categories of operators are used to define variables and instructions: arithmetic operators and logical (boolean) operators.

  • Arithmetic Operators: These operators perform common mathematical operations. They include addition, subtraction, multiplication, division, and others that are essential for numerical computations.

  • Logical (Boolean) Operators: These operators are used for comparing values and evaluating logical expressions. A boolean value represents one of two possibilities: true or false. Boolean values result from evaluating logical expressions and are used to make decisions within a program, such as executing certain actions when specific conditions are met.

Boolean values are crucial for control flow in programming, allowing for conditional execution based on whether a condition evaluates to true or false.

4.0. Arithmetic Operators#

Operation

Symbol

Example

Addition

+

x = 2 + 3

Subtraction

-

z = x - y

Multiplication

*

y = 3 * x

Real Division

/

5 / 2 = 2.5

Integer Division

//

5 // 2 = 2

Exponentiation

**

x ** 2 = x * x

Modulo (Remainder)

%

17 % 3 = 2

Increment Addition

+=

x += 4 (i.e., x = x + 4)

Increment Subtraction

-=

x -= 4 (i.e., x = x - 4)


4.1. Logical Operators#

Operation

Symbol

Description

Example

Logical AND

and

Returns True if both operands are true

True and False yields False

Logical OR

or

Returns True if at least one operand is true

True or False yields True

Logical NOT

not

Returns True if the operand is false

not True yields False

Logical XOR (Exclusive OR)

^

Returns True if operands are different

True ^ False yields True

Logical equality

==

Returns True if both operands are equal

x == y

Logical inequality

!=

Returns True if operands are not equal

x != y

Less than

<

Returns True if left operand is less than right operand

x < y

Greater than

>

Returns True if left operand is greater than right operand

x > y

Less than or equal to

<=

Returns True if left operand is less than or equal to right operand

x <= y

Greater than or equal to

>=

Returns True if left operand is greater than or equal to right operand

x >= y


x = 23j + 1
# Get help documentation
help(x.conjugate)
Help on built-in function conjugate:

conjugate() method of builtins.complex instance
    Return the complex conjugate of its argument. (3-4j).conjugate() == 3+4j.
# Get help documentation
help(x)
Help on float object:

class float(object)
 |  float(x=0, /)
 |
 |  Convert a string or number to a floating-point number, if possible.
 |
 |  Methods defined here:
 |
 |  __abs__(self, /)
 |      abs(self)
 |
 |  __add__(self, value, /)
 |      Return self+value.
 |
 |  __bool__(self, /)
 |      True if self else False
 |
 |  __ceil__(self, /)
 |      Return the ceiling as an Integral.
 |
 |  __divmod__(self, value, /)
 |      Return divmod(self, value).
 |
 |  __eq__(self, value, /)
 |      Return self==value.
 |
 |  __float__(self, /)
 |      float(self)
 |
 |  __floor__(self, /)
 |      Return the floor as an Integral.
 |
 |  __floordiv__(self, value, /)
 |      Return self//value.
 |
 |  __format__(self, format_spec, /)
 |      Formats the float according to format_spec.
 |
 |  __ge__(self, value, /)
 |      Return self>=value.
 |
 |  __getnewargs__(self, /)
 |
 |  __gt__(self, value, /)
 |      Return self>value.
 |
 |  __hash__(self, /)
 |      Return hash(self).
 |
 |  __int__(self, /)
 |      int(self)
 |
 |  __le__(self, value, /)
 |      Return self<=value.
 |
 |  __lt__(self, value, /)
 |      Return self<value.
 |
 |  __mod__(self, value, /)
 |      Return self%value.
 |
 |  __mul__(self, value, /)
 |      Return self*value.
 |
 |  __ne__(self, value, /)
 |      Return self!=value.
 |
 |  __neg__(self, /)
 |      -self
 |
 |  __pos__(self, /)
 |      +self
 |
 |  __pow__(self, value, mod=None, /)
 |      Return pow(self, value, mod).
 |
 |  __radd__(self, value, /)
 |      Return value+self.
 |
 |  __rdivmod__(self, value, /)
 |      Return divmod(value, self).
 |
 |  __repr__(self, /)
 |      Return repr(self).
 |
 |  __rfloordiv__(self, value, /)
 |      Return value//self.
 |
 |  __rmod__(self, value, /)
 |      Return value%self.
 |
 |  __rmul__(self, value, /)
 |      Return value*self.
 |
 |  __round__(self, ndigits=None, /)
 |      Return the Integral closest to x, rounding half toward even.
 |
 |      When an argument is passed, work like built-in round(x, ndigits).
 |
 |  __rpow__(self, value, mod=None, /)
 |      Return pow(value, self, mod).
 |
 |  __rsub__(self, value, /)
 |      Return value-self.
 |
 |  __rtruediv__(self, value, /)
 |      Return value/self.
 |
 |  __sub__(self, value, /)
 |      Return self-value.
 |
 |  __truediv__(self, value, /)
 |      Return self/value.
 |
 |  __trunc__(self, /)
 |      Return the Integral closest to x between 0 and x.
 |
 |  as_integer_ratio(self, /)
 |      Return a pair of integers, whose ratio is exactly equal to the original float.
 |
 |      The ratio is in lowest terms and has a positive denominator.  Raise
 |      OverflowError on infinities and a ValueError on NaNs.
 |
 |      >>> (10.0).as_integer_ratio()
 |      (10, 1)
 |      >>> (0.0).as_integer_ratio()
 |      (0, 1)
 |      >>> (-.25).as_integer_ratio()
 |      (-1, 4)
 |
 |  conjugate(self, /)
 |      Return self, the complex conjugate of any float.
 |
 |  hex(self, /)
 |      Return a hexadecimal representation of a floating-point number.
 |
 |      >>> (-0.1).hex()
 |      '-0x1.999999999999ap-4'
 |      >>> 3.14159.hex()
 |      '0x1.921f9f01b866ep+1'
 |
 |  is_integer(self, /)
 |      Return True if the float is an integer.
 |
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |
 |  __getformat__(typestr, /)
 |      You probably don't want to use this function.
 |
 |        typestr
 |          Must be 'double' or 'float'.
 |
 |      It exists mainly to be used in Python's test suite.
 |
 |      This function returns whichever of 'unknown', 'IEEE, big-endian' or 'IEEE,
 |      little-endian' best describes the format of floating-point numbers used by the
 |      C type named by typestr.
 |
 |  fromhex(string, /)
 |      Create a floating-point number from a hexadecimal string.
 |
 |      >>> float.fromhex('0x1.ffffp10')
 |      2047.984375
 |      >>> float.fromhex('-0x1p-1074')
 |      -5e-324
 |
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |
 |  __new__(*args, **kwargs)
 |      Create and return a new object.  See help(type) for accurate signature.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  imag
 |      the imaginary part of a complex number
 |
 |  real
 |      the real part of a complex number

To access the complete list of standard Python operators and their equivalent functions, see this page. You can also refer to this page for some examples of standard operator usage.

5. User input ( the input() function)#

In Python, the input() function is used to capture user input from the console. It pauses the program’s execution and waits for the user to type something, which is then returned as a string. This input can be stored in a variable, allowing you to use the entered data later in your code.

5.0. Basic Usage#

The basic syntax for the input() function is:

variable_name = input(prompt)
  • prompt: This is an optional argument. It is a string that is displayed to the user, providing instructions or asking for specific input.

  • variable_name: This is the variable that will store the value entered by the user.

Example#

Here’s a simple example of using the input() function:

name = input("Enter your name: ")
print("Hello, " + name + "!")

In this example:

  • The program prompts the user to enter their name.

  • The entered name is stored in the variable name.

  • The program then greets the user using the name provided.

name = input("Enter your name: ")
print("Hello, " , name)
Hello,   xcjk b jkv'
age = input("Enter your age: ")
print("Hello, " + name + "!")
type(age)
Hello, Yae!
str
x = 4
y = 6
x, y = y, x
x, y
(6, 4)
var_1 = True
var_2 = False

5.1. Important Notes#

  • Type Conversion: Since input() always returns the input as a string, you may need to convert it to the appropriate type (e.g., int, float) depending on the context.

    age = int(input("Enter your age: "))
    
  • Handling Errors: When converting input, it’s important to handle potential errors, such as the user entering a non-numeric value when an integer is expected.

  • Security Considerations: Be cautious when using input() in sensitive applications, as it can introduce security risks if the input is not properly validated or sanitized.

Using the input() function is a common way to make your Python programs interactive, enabling users to provide data that can be processed and utilized by the program.

So far we've hardcoded values. In real programs, you often need to get data from the user — let's see how.

5.2. Accepting User Inputs (as both integer and string)#

input(prompt) prompts for and returns input as a string. Hence, if the user inputs a integer, the code should convert the string to an integer and then proceed.

a = input("Hello, \nHow are you?  ") # \n means new line


print("================================== \n")
print(type(a))
try_something = input("Type something here and it will be stored in variable try_something \t")

print("================================== \n")
print(type(try_something))
number = input("Enter number: ")
name = input("Enter name: ")

print("\n")
print("Printing type of a input value")
print("================================== \n")
print("Type of number", type(number))
print("================================== \n")
print("Type of name", type(name))

5.3. eval() (accepting user inputs; only as integer)#

The eval() function in Python can be used in conjunction with input() to evaluate a string as a Python expression. This can be particularly useful when you want to allow the user to input a mathematical expression or Python code directly and have it evaluated at runtime.

Basic Usage of eval()#

The basic syntax for using eval() with input() is:

result = eval(input(prompt))
  • prompt: This is the text displayed to the user to guide them on what to input.

  • result: This variable stores the output after evaluating the user input as a Python expression.

Example#

Here’s an example where the user is allowed to input a mathematical expression, and eval() evaluates it:

expression = input("Enter a mathematical expression: ")
result = eval(expression)
print("The result is:", result)
expression = input("Enter a mathematical expression: ")
result = eval(expression)
print("The result is:", result)

In this example:

  • The program prompts the user to enter a mathematical expression.

  • The input is passed to eval(), which evaluates the expression.

  • The result is then printed out.

Important Notes#

  • Use with Caution: The eval() function can be dangerous if used with untrusted input, as it will execute any code passed to it. This could potentially lead to security vulnerabilities, such as code injection attacks. It should only be used in safe, controlled environments where the input is trusted.

  • Valid Python Expressions: The string passed to eval() must be a valid Python expression. If the string contains syntax errors or invalid operations, Python will raise an exception.

  • Alternative: In many cases, using int() or float() for type conversion, or safely parsing and evaluating input without eval(), may be preferable for security reasons.

Using eval() with input() can be powerful for dynamic code evaluation, but it should be used responsibly to avoid unintended consequences.

Practice Problem#

# Accept one integer and one float number from the user and calculate the addition of both the numbers.
num1 = int(input("Enter first number: "))
num2 = float(input("Enter second number: "))

result=(num1+num2)
print("Final result is: ", result)
# Write code to get three numbers and add first 2 number and multiply with third number

num1 = int(input("Enter first number: "))   # converting input value to integer
num2 = int(input("Enter second number: "))  # converting input value to integer
num3 = int(input("Enter third number: "))   # converting input value to integer

print("\n")
print("First Number: ", num1)
print("Second Number: ", num2)
print("Third Number: ", num3)

result=(num1+num2)*num3
print("Final result is: ", result)
# Write a code to get four numbers:
#Step 1. Multiply first and fourth number
#Step 2. Divide second and third number
#Step3. Add Step 1 and Step 2 outputs.

num1 = int(input("Enter first number: "))
num2 = int(input("Enter second number: "))
num3 = int(input("Enter third number: "))
num4 = int(input("Enter fourth number: "))

print("\n")
print("First Number: ", num1)
print("Second Number: ", num2)
print("Third Number: ", num3)
print("Fourth number: ", num4)

result=(num1*num4)+(num2/num3)
print("Final result is: ", result)
# Let’s see how to accept float value from a user in Python.
# You need to convert user input to the float number using
# the **`float()`** function as we did for the integer value.
float_number = float(input("Enter float number: "))  # converting input value to float
print("\n")
print("input float number is: ", float_number)
print("type is:", type(float_number))

🎯 Key Takeaways

  • Variables are created by assignment (=) and do not require type declarations.
  • Python supports multiple and parallel assignment: a, b = 1, 2.
  • Core types include int, float, str, bool, complex, and NoneType.
  • Use type() to inspect a variable's type and casting functions to convert between types.
  • Follow PEP 8 naming conventions: snake_case for variables and functions, PascalCase for classes.

🏁 End of Lecture 2 — Variables, Types, and Assignment

PyPro-SCiDaS • Python Proficiency for Scientific Computing and Data Science

Course progress: 17% complete (3 of 18 lectures)

© 2025 Yaé Gaba — CC BY-NC 4.0