Python for AI 101
Acknowledgement: This post is based mainly on Dr. Quang-Vinh Dinh’s presentation and slides and partly on on TA, STA, and peers’ responses from the course, AIO2025, offered by AI VIETNAM.
Relevance: The audience of this lecture were those who knew nothing about coding, have had some coding experience, and have known a bit of AI knowledge. Absolute beginners are encouraged to read the material and repeatedly practice coding without AI assistance to strengthen their coding and code-reading skills. Note that only necessary Python knowledge is introduced here.
Creating an error while coding is, in fact, a good sign which says you should keep going to figure out what the problem is and how to resolve it.
-Dr. Quang-Vinh Dinh
In today’s post, we’ll look at data representation, functions, and conditions. We’ll also discuss some applications in AI including Loss and Softmax functions.
Before getting into the main materials, I cannot stress enough how important it is to comment on your code.
Pro tip: Annotate your code - always!
Keeping documentation of what your code does is far more important than most people might think. Your log isn’t for today but tomorrow. It benefits not only future you but your colleagues or anyone else trying to read or maintain your code.
- Use
#for single-line comments - Use
'''or"""for multi-line comments and docstrings.
Introduction
We consider Python as a tool that alllows us to transform our ideas into a program producing desired results. Don’t worry about becoming an expert in Python since it, just like other programming languages, is a means of solving problems but a goal to reach. Essentially, you need to know its syntax and structure.
It’s usually easier to learn something when we know its history and why it is studied or used. The same goes for Python. Python is widely adopted in the community of Data Science and Machine Learning because it has a giant and vibrant ecosystem with plentiful frameworks, libraries, and packages of diferrent purposes. Some examples can be found in the table below.
| Purposes | Frameworks | Libraries | Packages |
|---|---|---|---|
| Scientific Computing | Pandas | NumPy | |
| Visualization | matplotlib, plotly | ||
| Machine Learning and Deep Learning | TensorFlow, Pytorch | Keras | |
| Natural Language Processing | Natural Language Toolkit (NLTK), GENSIM, spaCy |
To write and run a program in Python, you can choose among some options such as Google Colab, Jupyter, Visual Studio Code, and PyCharm. It’s not difficult to look for a video or post which guides you install and/or use them.
python history
Data Representation
In Python, data can be represented in three groups discussed below. In any programming language, data is stored in a container called variable. This allows us to refer to and manipulate the data later. In Python, defining a variable is straightforward.
variable_name = variable_value
We may think of a variable as the name of the container and its value as the content held inside it. We are allowed to use and/or modify the value as needed.
mystery_box = 'IPhone'
# a container called *mystery_box* has a value of *'IPhone'* in it.
Now, you may ask, What can I can name a variable? Are there any conventions I should be aware of?
In Python, variable naming follows specific rules and conventions.
- Avoid keyword: A syntax error is returned when a keyword is used as a variable. Usually, editors display a red squiggly underline under such a variable name.
- Meaningful name: While we can name a variable almost anything, using a name that reflects its purpose is best practice.
- snake_case: Using lowercase words separated by underscores for a variable name follows PEP8—standard Python style guide.
Primitive Data Types
There are three main categories of primitive data types including logic, number, and text.
| Plain Language | Python Language | Examples |
|---|
Note: the quotation marks used in a string must be consistent—a string starts with a double quote must end with a double quote, not a single quote, and vice versa.
Overflow and Underflow: No matter how much memory a programming language can access, there are always limits to the size of numbers it can represent. When a number exceeds the maximum value the system can handle, it causes an overflow and Python returns inf for infinity. Conversely, it leads to an underflow when a number is too close to zero and Python returns 0.0.
Application in AI: Since computers can only understand numeric values, any text we want a machine to process must be converted into nnumerical format. This is a core task in Natural Language Processing (NLP)—the field that helps machine understand human language. Not familiar with NLP?. That’s totally fine! Just have in mind Google Translate—a popular example of NLP in action.
Abstract Data Structures
Primitive data representation are great for simple tasks, but they fall short when things get more complex. That’s when built-in data structures like lists and dictionaries come in. We’ll introduce their definitions here and dive deeper into how they work in future posts.
List
list_name = [element_1, ..., element_n]
A list is a collection of elements and each of them is automatically assigned to an index. Forward indices start at 0 for the first item on the left and increase by one for each following element. In practice, you access an element’s values via its index. Let’s take a look at an example.
# create a list of fruits
fruits = ['apple', 'orange', 'banana', 'grape', 'mango']
# test
fruits[0]
>>> 'apple'
fruits[2]
>>> 'banana'
'''
Of course, elements of a list can be logic, numbers, another list and even more.
data = [5, 4.7, -2, 'hello', 0, True, -1000.1]
Dictionary
dictionary_name = {key_1: value_1, ..., key_n: value_n}
Another common and powerful data structure is the dictionary. Think of a regular dictionary book: a word has a meaning(s) and no word appears more than once.
A dictionary in Python is created in a similar fashion where it is a collection of two-part elements and each unique key has a specific value. In a dictionary, an item’s value can be retrieved using its key in lieu of index. Here’s a simple example.
# create a dictionary of a fruit's characteristics
fruit = {'name': 'avocado', 'type': 'berry', 'nutrition': ['fat', 'fiber', 'vitamins'], 7: 100}
# test
fruit[7]
>>> 100
fruit['nutrition']
>>> ['fat', 'fiber', 'vitamins']
Other Data Representation
Tabular and Image Data are predominant in Data Analysis. They are both handled using matrix formats.
Functions
def function_name(parameter_1, ..., parameter_n):
'''
do docstring here.
'''
# code here
return result
Why Functions?
Imagine you want a machine to make a sandwich for you every morning.
- It’d be time-consuming to tell it all the steps every single day just to do one job. Wouldn’t it be better if it receives one line of request and automatically undertake all the tasks. That’s exactly what functions are for. It lets us wrap a block of code into one reusable command, that we just need to call the function to handle the work rather than rewriting the entire instruction.
- Let’s say there are many steps for this sandwich-making process. Sure, you could certainly put all the actions in one go—write all the tasks in one function. But it will improve readability if we separate the tasks into logical parts—one for preparation and another for cooking. As such, we know exactly how to allocate a set of actions to one block of time and reuse those sets in other recipes.
| Get the ingredients | Put the ingredients together |
|---|---|
| Get two slice of breads | Use the knife to spread peanut butter on one side of a slice |
| Get the peanut butter container | Use the knife to spread peanut butter on one side of the other slice |
| Get a knife | Put the peanut butter sides of two slices together |
What is a Function?
In Python, a function is a reusable block of code that
- Takes parameters (inputs), performs an action within itself, and optionally returns outputs.
- Might not have inputs or outputs.
- Must start with the
defkeyword. - Should end with the
returnkeyword.- If no outputs, put
return None.
- If no outputs, put
- Should be named with a verb to indicate its action and written in snake_case.
- Default parameters must follow non-defaults.
- Parameters can be set to default values but they can take other values.
- Body must be indented.
✅ # default arguments come last
def compute_total_income(bonus, salary = 100000):
# function body
❌ # default arguments are in wrong position
def compute_total_income(salary = 100000, bonus):
# function body
Types of Functions
Two main types of functions are built-in functions and user-defined functions.
Built-in Funtions
Built-in functions are created by and freely available to the Python community. Python comes with a variety of built-in functions that are ready to use. Two common ones are print() for displaying outputs and type() for returning the data type of a variable. We can use them in any Python program without extra setup needed.
Some useful functions live inside special packages called module like random and math. To use those functions, we need to import the module first via the import keyword. Try out the code below and see what it gives us.
import math
x = 4
y = -3
print(math.sqrt(x))
print(math.sqrt(y))
print(math.fabs(x))
print(math.fabs(y))
print(math.log(math.e)) # log is based e
Practice Exercises
s = 'Hello World'
print(s)
import math
number = 20.2
print(math.floor(number))
a = 5
Print(a)
a = 5
c = a + b
print(c)
lst = [1, 2, 3, 4, 5]
print(l[1])
print(l[5])
a = 5
s = 'AI'
print(a + s)
a = 5
b = 2
print(a / b)
s = 'hello world'
print(s[0])
print([7])
Applications in AI
Square Root Function $\sqrt{x}$ plays a key role in Object Detection problems. Since the movemnet of an object is measured relative to its size, applying this function can help normalize the change and respond to this challenge.
import math
a = -1
b = 1000
c = 0
math.sqrt(a)
>>> ValueError
math.sqrt(b)
>>> 31.622776601683793
math.sqrt(c)
>>> 0.0
Logarithm Function $\log({x})$ has a couple of extremely useful properties:
- $\log({1}) = 0$
- It is monotonically increasing, meaning that $\text{if } x_1 < x_2, \text{ then } f(x_1) < f(x_2)$.
These properties are applied in Optimization Algorithms problems which are everywhere in Machine Learning.
- When we try to maximize a function, evaluating its logarithm is often computationally easier and faster than the function itself while the location of the maximum stays the same.
- Logarithms can be used when our focus is on how numbers are relative to each other each other rather than their actual values.
- Since log of a number grows and reduces much more slowly than the number itself, the program can easily avoid the overflow and underflow issues.
import math
a_1 = 0.00004
b_1 = 0.00003
a_2 = 0.04
b_2 = 0.03
# test
m_1 = a_1 * b_1
m_2 = a_2 * b_2
print('m_1 is', m_1, 'and m_2 is', m_2)
print('m1 is smaller than m2:', m_1 < m_2)
l_1 = math.log(a_1) + math.log(b_1)
l_2 = math.log(a_2) + math.log(b_2)
print('l_1 is', l_1, 'and l_2 is', l_2)
print('l1 is smaller than l2:', l_1 < l_2)
'''
m_1 is 1.2e-09 and m_2 is 0.0012
m1 is smaller than m2: True
l_1 is -20.541 and l_2 is -6.725
l1 is smaller than l2: True
'''
Exponential Function $\exp({x}) \in (0, \infty) \text{ when } x \in (-\infty, \infty)$ has an extremely useful property:
- $\exp({x}) \in (0, \infty) \text{ when } x \in (-\infty, \infty)$ turns all values into positive numbers.
This property allows exponential functions used for datasets containing both positive and negative numbers. It is a key for $\exp({x})$ to be used in the Softmax Function, which determines how an object and the background of an image are related.
- Softmax helps avoid the overflow issue from the exponential function.
- A rabbit/snake near a bush gives a postive relation
- Fish in a bush gives a negative relation, unless you can show me evidence of a live fish being on land.
import math
a = -7
b = 7
c = 1000
# test
math.exp(a)
>>> 0.0009118819655545162
math.exp(b)
>>> 1096.6331584284585
math.exp(c)
>>> OverflowError
Now you may ask, How do I know which function(s) to use provided a problem?
That’s a great question! Let’s look at an example and we’ll walk through the thought process to develop and improve a solution.
Design a Loss Function
Problem statement: There are ten balls, nine reds and one blue, in a basket. If you pick up a ball from the basket, would getting a red or blue surprise you more?
Breakdown:
- $R$ and $B$ are the events of getting a red and blue ball, respectively.
- $E$ is the event of getting a ball.
- $p(E)$ is the probability of something happen or our believe.
- $s(E)$ is the level of surprise.
- $f(p)$ is the symbolic level of surprise.
- We should first compute the probability of getting a ball.
- $p(R) = \frac{9}{10} = 0.9$
- $p(B) = 1 - p(R) = 0.1$
- Since $p(R) > p(B)$, we want $s(R) < s(B)$. There are two ways to build $s(E)$ satisfying this condition.
- A linear function $s(E) = 1 - p(E)$
- A non-linear function $s(E) = \frac{1}{p(E)}$
- Have in mind that $p(E) \in [0, 1]$, so $s(E) = \frac{1}{p(E)} \in [1, \infty)$. This means $s(E) = 1$ shows no surprise, which is mathematically strange. It'd be more logical to have no surprise as $0$.
- We desire to achieve the level of surprise in $[0, \infty)$ instead. Note that two important properties of logarithm are
- $\log({1}) = 0$: helps convert $1$ to $0$ as wanted
- Logarithm is monotonic: $f(p) = \log({s(E)}) = \log{\frac{1}{p(E)}} = -\log({p(E)})$ is proportional to $s(E)$ as we need $f(p)$ also interprets the level of surprise.
- Computing $f(p)$ is more convenient that $s(E)$ since the logarithmic graph approaches $\infty$ significantly more slowly than that of $s(E)$.
Design the Softmax Function
Problem statement: Given a list of data, what is the percentage of each data over their sum? Note that data can be positive, negative, and zero.
Breakdown:
- $Z = \{z_1, \cdots, z_n\}$ where $z_i \in (-\infty, \infty)$.
- $S = \sum_{j=1}^{n} z_j = z_1 + \cdots + z_n$ is the sum of all data in $Z$.
- $p_i = f(z_i)$ is the probability of $z_i$ over $S$.
- Have in mind that $\exp({x}) \in (0, \infty)$ where $x \in (-\infty, \infty)$.
- $Z = \{e^{z_1}, ..., e^{z_n}\}$ where $e^{z_i} > 0$ as wanted.
- $S = \sum_{j = 1}^{n} e^{z_j}$.
- $p_i = f(z_i) = \frac{e^{z_i}}{\sum_{j = 1}^{n} e^{z_j}}$ is the desired probability.
User-defined Functions
In addition to built-in functions, users are allowed to custom functions for specific purposes. Some critical information about user-defined functions is:
- A function is recommended to be defined at the beginning of the program.
- A function does nothing until it is called.
- A function is immediately canceled once its task is completed during the call.
- A function does not necessarily return a value.
- The
returnstatement sends a value when the call is finished. -
return Noneis recommended if there’s no value to return.
- The
A helpful analogy of a function in a program is a room in a house. We enter when we need to do something inside and leave once we’re done. If we need to take something out of the room, you need to bring a container to hold it. Otherwise, you simply walk in and out empty-handed.
Let’s see this idea in action. When the function is called, any argument passed to it is handed over to a new context where they are processed. Eventually, the function gives out a created-inside-the-function value and shuts down/cancels. Thus, all the variables defined inside the function disappear. If variables inside and outside a function are named the same, the one outside is still accessible to the main program whatsoever.
def compute_salary(salary):
'''
This function aims to increase the salary of an employee
salary (float): the salary of a person
return (float): the new salary of a person
'''
new_salary = salary + 7000
return new_salary
salary_p1 = 60000
# call function compute_salary()
# pass arguments: salary_p1 and to it
result = compute_salary(salary_p1)
result
>>> 67000
# test
new_salary
>>> NameError: name 'new_salary' is not defined
Let’s implement a simple math problem in Python.
Estimate the Area of a Unit Circle.
Breakdown:
- $r = 1$ is the radius of the circle.
- $\alpha$ is the angle in degree starting at positive $x-axis$.
- $A_{est}$ is the estimated area of the circle.
- $A_{real}$ is the real area of the circle.
- Divide the circle into equal circular sectors:
- Their angle for each sector is $\alpha$
- The number of sectors is $n = \frac{360}{\alpha}$.
- Create triangles out of those sectors. There are two ways, either an isoceles or a right triangle.
- An isoceles triangle: $A_{\alpha} = \frac{(r)(r) \sin({\alpha})}{2} = \frac{(1)(1) \sin({\alpha})}{2} = \frac{\sin({\alpha})}{2}$
- A right triangle: $A_{\alpha} = \frac{height * base}{2} = \frac{\sin({\alpha}) \cos({\alpha})}{2}$.
- Those triangles roughly cover the circle, so their area sum is the estimated area of the circle.
- Isoceles triangles: $A_{real} \approx A_{est} = n A_{\alpha} = \frac{360}{\alpha} \frac{\sin({\alpha})}{2}$
- Right triangles: $A_{real} \approx A_{est} = n A_{\alpha} = \frac{360}{\alpha} \frac{\sin({\alpha}) \cos({\alpha})}{2}$
import math
def estimate_area(alpha):
'''
This functions aim to estimate the area of a unit circle
using isoceles triangle method
alpha (float): the size of an angle in degree
return (float): the estimated area of a unit circle
'''
# compute sine and cosine
radian_alpha = math.radians(alpha)
sin_alpha = math.sin(radian_alpha)
# compute the alpha area
area_alpha = sin_alpha / 2
area = area_alpha * (360 / alpha)
return area
# test
print(estimate_area(10))
print(estimate_area(1))
'''
3.125667198004746
3.141433158711032
'''
Practice Exercises
|
|
Exercise 3: Write code to compute softmax function based on the above design.
Exercise 4: Write a function to compute estimate the area of a circle using right triangle method in the above example.
Exercise 5: What is the output of the following?
def a_function(n):
return a_function(n)
a_function(5)
def a_function(x):
a_var = 3
result = x * a_var
return result
a_var = 4
print(a_var)
print(a_function(10))
Branching/Conditions
Conditional statements in Python enables the execution of certain code blocks based on whether a condition is true or false.
Comparison Operators
Comparison operators are symbols used to compare two values and create a condition for a conditional statement.
| Operator | Math | Meaning |
|---|---|---|
| $==$ | $=$ | Equal |
| $!=$ | $\neq$ | Not equal |
| $>$ | $>$ | Greater than |
| $<$ | $<$ | Less than |
| $>=$ | $\geq$ | Greater than or equal |
| $<=$ | $\leq$ | Less than or equal |
Basic Conditional Statements
We’ll introduce three types of conditional statements. Note that the else statement is optional for the last two.
- if: if ‘if’ is satisfied, do it; otherwise, move on.
- if-else: if ‘if’ is satisfied, do it and ignore ‘else’; otherwise, do ‘else’.
- if-elif-else: if ‘if’ is satisfied, do it and ignore the rest; otherwise, check ‘elif’ and if it is true, do ‘elif’ and ignore ‘else’; otherwise, do ‘else’.
Imagine there are two or three doors and you have a key that can unlock exactly one of them. You need to check one by one and once you open the right door, you can walk through without checking the rest.
The process of these statements is illustrated using flowcharts which use shapes and arrows to depict steps and decisions as follows.
flowchart TB
subgraph C [IF-ELIF-ELSE]
direction TB
C1[before if] --> C2{if condition}
C2 -->|True| C3[inside if] --> C7[after if-elif-else]
C2 -->|False| C4{elif condition} -->|True| C5[inside elif] --> C7
C4 -->|False| C6[inside else] --> C7
end
subgraph B [IF-ELSE]
direction TB
B1[before if] --> B2{if condition}
B2 -->|True|B3[inside if] --> B5[after if-else]
B2 -->|False|B4[inside else] --> B5
end
subgraph A [<strong>IF</strong>]
direction TB
A1[before if] --> A2{if condition}
A2 -->|True| A3[inside if] --> A4[after if]
A2 -->|False| A4
end
style C2 fill:#ffdab9
style C4 fill:#ffdab9
style B2 fill:#ffdab9
style A2 fill:#ffdab9
style C3 fill:#c6f777
style C5 fill:#c6f777
style C6 fill:#c6f777
style B3 fill:#c6f777
style B4 fill:#c6f777
style A3 fill:#c6f777
import math
a = 99
b = 4
# if-else
if a < 0:
result_1 = b * b
else:
result_1 = math.sqrt(b)
result_1
>>> 2.0
# if-elif-else:
if a < 0:
result_2 = b * b
elif a >= 0:
result_2 = math.sqrt(b)
result_2
>>> 2.0
ApplicationS in AI
We can use conditional statements for activation functions in Machine Learning like ReLU
In practice, rule-based chatbots, automatic chats/replies on websites, are built according to this branching condition idea. The interface for these chatbots can be constructed using streamlit.
DEMONSTRATION VIDEO
One side note is that the if-else and if-elif-else statements can be converted into one mathematical function, even one calculation. This is extremely helpful since
- we can turn any data into vectors or matrices which computers handle best
- we only need to do one computation for get the result
- we can use math to work on real-world problems.
Practice Exercises
Exercise 2: What is the output of the function in exercise 1 for the following?
- a = -99, b = 4
- a = 0, b = 4
Exercise 4: Draw a flowchart for the demonstration video above and write a program with a function for it.
FAQ
Here are some good questions asked during class. The answers to these questions came from either some admin, TA, STA, or members of AIO2025.
| Questions | Answers |
|---|---|
| Does a program run the comments? | No. The comments are only for the owners and readers. |
| What are real-life applications of a logarithm function? | Information theory (entropy), Astronomy (lights’ and stars’ brightness), Machine learning (logistic regression, cross-entropy) |
| What are values modified for? | Value modification is to avoid disadvantageous scenarios like overflow, underflow, slow computations, errors, divergent sequences. Some functions are used to change the range so that values are easier to be dealt with but still preserve core characteristics. |
| If one module needs a supporting one, do I need to import the latter? | No. Modules consist of their supporting modules. |
| Where do I look for a function that I need? | dir() shows attributes of an object or help() provides detailed documentation. |
| What is the difference between parameters and arguments? | Parameters are like variables or placeholders while arguments are like values. |
Enjoy Reading This Article?
Here are some more articles you might like to read next: