Python Fundamentals & Simple Types

Session 1 — Chapter 1: Introduction · Chapter 2: Variables and Simple Data Types

Python for Information Security
>>> print("Hello world!")
Hello world!

Agenda

Chapter 1 — Introduction
01

History of Python

02

Getting Started with Python

Setting up the environment · Installing a code editor

03

Writing hello_world.py

Running · Troubleshooting · Terminal (Windows) · macOS & Linux

Chapter 2 — Variables & Simple Data Types
01

Variables

Naming · Avoiding name errors · Variables as labels

02

Strings

Case · f-strings · Whitespace · Stripping · Syntax errors

03

Numbers

Integers · Floats · Int vs float · Underscores · Multiple assignment · Constants

04

Comments

How to write · What to write · Exercises · Chapter summary

Learning Outcomes

What learners will be able to do after this session:

Python Origins & Design

Explain where Python came from, its major release milestones, and the design principles codified in the Zen of Python (PEP 20).

Install & Run

Install Python 3, choose an editor, and run a .py script from both an editor and a terminal on Windows, macOS, and Linux.

Variables & Errors

Create and name variables correctly following PEP 8 conventions; read and interpret a traceback (NameError, SyntaxError).

Strings, Numbers & Comments

Manipulate strings (case methods, f-strings, strip), work with int and float types, define constants, and write purposeful comments.

History of Python

Origins: From ABC to Python

Python was conceived in the late 1980s by Guido van Rossum at CWI (Centrum Wiskunde & Informatica) in the Netherlands. Before creating Python, van Rossum worked on the ABC language team at CWI. Python inherited several key ideas from ABC: indentation for grouping blocks, high-level built-in types, and an emphasis on readability.

In his own words, he built "a simple virtual machine, a simple parser, and a simple runtime," using indentation for statement grouping and a small set of core data types: dictionaries (hash tables), lists, strings, and numbers.


History of Python

Why the Name "Python"?

Ngắn - Độc - Vui

Common Assumption 🐍

Many people assume Python is named after the large constrictor snake — a reasonable guess given the reptile logo used in some contexts.

This is not the actual origin of the name.

Actual Origin 📺

The name comes from the BBC comedy series Monty Python's Flying Circus (1969–1974). Guido van Rossum was a fan of the show and wanted a name that was short, unique, and slightly irreverent.

Van Rossum started the interpreter as a hobby project during Christmas week of December 1989. The official Python FAQ confirms this naming origin.

History of Python

Timeline of Major Releases

1

Feb 1991 — v0.9.0

Posted to alt.sources. Classes with inheritance, exception handling, functions, core types (list, dict, str), module system.

2

Jan 1994 — v1.0

Added functional programming tools: lambda, map, filter, reduce.

3

Oct 2000 — v2.0

List comprehensions, cycle-detecting garbage collector, Unicode support.

4

Dec 2008 — v3.0

"Python 3000" / "Py3K" — intentionally not backward compatible with 2.x. A clean break.

5

Jan 1, 2020 — Python 2 EOL

Python 2 reached end of life. No further security updates or bug fixes.

History of Python

Python 2 vs Python 3

This course uses Python 3 exclusively. The table below summarizes the key differences. Python 2 has been end-of-life since January 1, 2020.

History of Python

The Zen of Python (PEP 20)

>>> import this

Beautiful is better than ugly.

Explicit is better than implicit.

Simple is better than complex.

Readability counts.

Errors should never pass silently.

Unless explicitly silenced.

In the face of ambiguity, refuse the temptation to guess.

There should be one— and preferably only one —obvious way to do it.

🔒 Security Reading

"Errors should never pass silently" — silent failures hide attacks and bugs. In security code, every exception must be logged or handled deliberately.

"Explicit is better than implicit" — magic behavior obscures what code actually does. Secure code should make data flows, permissions, and error paths visible and auditable.

These two aphorisms underpin defensive programming practices that will appear throughout this course.

History of Python

Zen of Python as a Security Rulebook

Two PEP 20 principles that decide whether your code is defensible.

Errors should never pass silently

Never swallow errors.

Common student habit — dangerous code ❌

try:
    verify_token(user_token)  # Authenticate the user
except:
    pass  # Ignore so the program doesn't crash

Security impact: Forged tokens or brute-force attempts trigger errors that the system silently swallows. Admins lose all monitoring traces (a blind spot) and never know an attack is underway.

✅ Defensive rule

Catch every exception specifically and log or audit it clearly. If an error is deliberately ignored, give an explicit justification (unless explicitly silenced).

Explicit is better than implicit

Be explicit, not implicit.

Common student habit — dangerous code ❌

Relying on "magic" behavior, such as implicitly assuming data types or implicit permissions (for example, if no role is passed, silently assume the user role).

Security impact: Attackers can exploit implicit behavior to disrupt the data flow or escalate privileges (privilege escalation).

✅ Defensive rule

Make permission checks, data types, and error paths explicit, line by line. The more explicit the code, the easier it is for the whole team to run code reviews and audits and spot vulnerabilities.

History of Python

Python Today and in Information Security

Python's Reach in 2024

GitHub Octoverse 2024 reports that Python overtook JavaScript as the most-used language on GitHub — a significant milestone reflecting Python's dominance in data science, automation, and security tooling.

Python also appears at or near the top of the TIOBE Index, a long-running measure of language popularity based on web search volume.

Security Tools Written in Python

Scapy

Packet crafting and analysis

sqlmap

SQL injection testing

Volatility 3

Memory forensics

Impacket

Network protocol library


Getting Started

How Python Runs Code

Compiled or Interpreted?

Python is commonly called an interpreted language. More precisely, CPython (the reference implementation, written in C) compiles source to bytecode, then interprets that bytecode on a virtual machine. The bytecode is cached in __pycache__.

import dis
dis.dis('print("hi")')
# → bytecode instructions
Setting Up the Environment

Which Python Version to Install

The coursebook (2022) required Python 3.6 or newer (f-strings were introduced in 3.6). Current best practice is to install a version that is still actively supported. The official Python Developer's Guide lists all versions and their end-of-life dates.

Release Lifecycle Phases

1

Feature

New features accepted

2

Bug Fix

Only bug fixes

3

Security

Security patches only

4

End of Life

No further updates

Python 3.11 Performance Note

Python 3.11 is documented as 10–60% faster than 3.10 (average 1.25× on the standard benchmark suite). For computationally intensive security tools, choosing a current version matters.

Setting Up the Environment

Installing Python 3 on Each OS

Setting Up the Environment

The Interactive Interpreter (REPL)

Terminal Session

$ python3
Python 3.x.x ... on linux
Type "help", "copyright", "credits" or "license"
for more information.
>>> print("Hello Python interpreter!")
Hello Python interpreter!
>>> exit()

The prompt >>> signals Python is waiting for a statement. The line beneath is the output. REPL stands for Read–Eval–Print Loop.

REPL vs Script File

Setting Up the Environment

Virtual Environments — Modern Practice

Why Use a Virtual Environment?

A virtual environment keeps each project's packages separate from the system Python and from other projects. This prevents version conflicts between dependencies.

For security work, tools such as Scapy and Impacket pin specific dependency versions. Isolation avoids conflicts and keeps the system Python clean.

python3 -m venv .venv
source .venv/bin/activate  # macOS/Linux
.venv\Scripts\activate     # Windows
pip install requests

One System — Many Isolated Projects

Each project folder gets its own .venv directory containing a private copy of the Python interpreter and installed packages. Activating a venv changes the shell's PATH so the project's Python is used first.

Installing a Code Editor

Choosing a Code Editor

The coursebook uses Sublime Text. The table below compares it with editors common in 2024.

First Program

Writing hello_world.py

1

Create a folder

Name it python_work — lowercase letters and underscores, following Python naming conventions.

2

Create the file

Create hello_world.py inside the folder. The .py extension tells both the editor and the OS that this is Python source code.

3

Type one line

print("Hello Python world!")
4

Save

Save the file. The program is now ready to run.

File Tree

python_work/
└── hello_world.py

The "Hello, World" Tradition

If this one line runs without error, the installation and editor are correctly configured. The "Hello, World" test is a quick sanity check used in virtually every programming course and environment setup guide.

Running hello_world.py

Running hello_world.py from the Editor

Sublime Text

Navigate to Tools → Build (shortcut: Ctrl+B on Windows, Cmd+B on macOS). The output panel at the bottom of the editor shows:

Hello Python world!
[Finished in 0.1s]

VS Code

Click the ▶ Run Python File button in the top-right toolbar, or open the integrated terminal and type:

python3 hello_world.py

Output appears in the terminal panel below the editor.

Troubleshooting

Reading a Traceback

Intentional Error — Missing Closing Parenthesis

print("Hello Python world!"

Output

  File "hello_world.py", line 1
    print("Hello Python world!"
         ^
SyntaxError: '(' was never closed

Anatomy of the Traceback

1

File & Line Number

File "hello_world.py", line 1 — identifies exactly where the error occurred.

2

Offending Code

The line is printed with a caret ^ pointing to the location Python identified as problematic.

3

Error Type & Message

SyntaxError: '(' was never closed — the error class and a human-readable description.

A traceback is Python's structured report of where and why execution failed. Reading it bottom-up is the first debugging step. Python 3.10+ provides more precise error messages.

Troubleshooting

Troubleshooting Checklist

  • Read the traceback — note file, line number, and error type.
  • Check syntax: colons, matching quotes, matching parentheses, letter case.
  • Take a short break and re-read the code with fresh eyes.
  • Start over: delete and recreate hello_world.py — no need to reinstall software.
  • Ask someone to follow the same steps on another machine.
  • Ask the community — describe what you tried, what you expected, and what you got.

Modern Addition: AI Assistants

AI coding assistants can explain a traceback and suggest a fix. However, the learner must still:

  • Verify that the suggested fix is correct
  • Understand why the fix works
  • Ensure no new bugs were introduced

Understanding the error — not just applying a patch — is the goal.

Running from a Terminal

Running Python from a Terminal — Windows

Command Prompt Session

C:\> cd Desktop\python_work
C:\Desktop\python_work> dir
hello_world.py
C:\Desktop\python_work> python hello_world.py
Hello Python world!

Command Breakdown

cd

Change directory to the folder containing the file.

dir

List files in the current directory — confirms hello_world.py is present before running.

python hello_world.py

Invoke the Python interpreter and pass the script as an argument.

Running from a Terminal

Running from a Terminal — macOS and Linux

Shell Session

~$ cd Desktop/python_work/
~/Desktop/python_work$ ls
hello_world.py
~/Desktop/python_work$ python3 hello_world.py
Hello Python world!

Windows vs macOS/Linux Commands

Chapter 1 — Key Takeaways

Origins & Philosophy

Created by Guido van Rossum (1989–1991), named after Monty Python, guided by PEP 20 (Zen of Python).

Use Python 3

Python 2 reached end of life on January 1, 2020. All code in this course targets Python 3.

CPython & Bytecode

CPython compiles source to bytecode and runs it on a virtual machine — not direct machine code execution.

Two Ways to Run Code

REPL (>>>) for experiments; .py scripts for programs. Both produce the same output for the same code.

Reading Tracebacks

Errors produce tracebacks — read file name, line number, and error type first. Always work bottom-up.

Chapter 2

Variables and Simple Data Types

What really happens when hello_world.py runs? The interpreter reads the file, identifies each token: print followed by parentheses → call the function and display what is inside the parentheses.

print("Hello Python world!")
# ↑ function name ↑ string literal ↑ call parentheses
Variables

Code

message = "Hello Python world!"
print(message)

message = "Hello Python Crash Course world!"
print(message)

Output

Hello Python world!
Hello Python Crash Course world!

Key Concepts

Name → Value Binding

The variable name message is bound to a value (the string). The value can be changed at any time; Python always uses the current binding.

Dynamic Typing

No type declaration is needed. The type belongs to the value, not the name.

Naming and Using Variables

Rules and Guidelines for Variable Names

Rules (errors if broken)

Only letters, digits, underscores; cannot start with a digit.
message_1 ✔ — 1_message ✘

No spaces in names.
greeting_message ✔ — greeting message ✘

Cannot be a keyword: class, if, for, import, …

import keyword
print(keyword.kwlist)

Guidelines — PEP 8 Style

Short but descriptive: name > n; student_name > s_n

Use lowercase_with_underscores (snake_case)

Avoid l (lowercase L) and O (uppercase o) — confused with 1 and 0

Avoid shadowing built-in names: print, list, str

Avoiding Name Errors

Avoiding Name Errors When Using Variables

Code with Intentional Typo

message = "Hello Python Crash Course reader!"
print(mesage)

Traceback

Traceback (most recent call last):
  File "hello_world.py", line 2, in <module>
    print(mesage)
NameError: name 'mesage' is not defined.
Did you mean: 'message'?

Reading the Traceback

1

Line Number

line 2 — Python found the error on line 2.

2

Offending Line

print(mesage) — the misspelled name that Python cannot find.

3

Error Type

NameError — the name was never defined in the current scope.

Variables Are Labels

Variables Are Labels, Not Boxes

Two Mental Models

Box Model (simplification)

A box named message contains the string. Implies the variable stores a copy of the value.

Label Model (Python's actual model)

The object "Hello" lives in memory. The name message is a label — a reference — pointing to that object.

Demonstrated with Code

a = "python"
b = a
print(a is b)        # True — same object
print(id(a) == id(b)) # True — same memory address

Assignment binds a name to an object; it does not copy the object. Both a and b refer to the same string in memory.

Variables

Dynamic Typing and type()

Every Value Has a Type

x = 42
print(type(x))   # <class 'int'>

x = 3.14
print(type(x))   # <class 'float'>

x = "42"
print(type(x))   # <class 'str'>

The same name x is rebound to values of different types. Python determines the type at runtime, not at compile time.

Simple Types in This Chapter

Strings

Strings

A string is a sequence of characters. In Python 3, str stores Unicode text — both single and double quotes are valid delimiters.

Double Quotes

"This is a string."
'I said, "Python!"'

Single Quotes

'This is also a string.'
"Python's syntax is clean."

Unicode Support

In Python 3, str natively stores Unicode. Text such as "An toàn thông tin" works without special handling.

Changing Case

Changing Case with Methods

Code

name = "ada lovelace"
print(name.title())  # Ada Lovelace
print(name.upper())  # ADA LOVELACE
print(name.lower())  # ada lovelace

Method Syntax

name . title ( )
# ↑ variable
#      ↑ dot operator
#        ↑ method name
#              ↑ parentheses (arguments here, empty)

Method Reference

Security Angle

Why lower() Matters in Security Code

Scenario: Comparing Domains

allowed_domain = "ptit.edu.vn"
user_domain = "PTIT.EDU.VN"

print(user_domain == allowed_domain)
# False — bypass!

print(user_domain.lower() == allowed_domain)
# True — correct

Key Message

Normalize case (and whitespace — see 2.2.4) before comparing. Otherwise, allow-lists and block-lists can be bypassed using case variations such as "Admin" vs "admin".

Why This Matters

Case-Insensitive by Specification

Domain names are case-insensitive by RFC 4343 — PTIT.EDU.VN and ptit.edu.vn refer to the same host.

Normalization Before Comparison

Any security check that compares strings — usernames, email domains, file extensions, command names — should normalize case first.

Consistent Storage

Store values in a canonical form (e.g., always lowercase) so lookups are consistent and predictable.

f-strings

Using Variables in Strings: f-strings

Code

first_name = "ada"
last_name = "lovelace"
full_name = f"{first_name} {last_name}"
message = f"Hello, {full_name.title()}!"
print(message)
# Hello, Ada Lovelace!

Syntax Rules

Prefix the opening quote with f (or F).

Expressions inside { } are evaluated and their results inserted into the string.

Any valid Python expression works inside the braces — including method calls like .title().

f-strings Were Introduced in Python 3.6

PEP 498 added f-strings as a concise, readable alternative to str.format(). They are the recommended approach for string interpolation in this course.

Python 3.8 Debugging Specifier

port = 443
print(f"{port=}")
# port=443

The = specifier inside braces prints both the expression and its value — useful for quick debugging.

String Formatting Styles

Three Ways to Build Strings

Whitespace

Adding Whitespace with Tabs and Newlines

Code & Output

print("Python")
# Python

print("\tPython")
#     Python

print("Languages:\nPython\nC\nJavaScript")
# Languages:
# Python
# C
# JavaScript

print("Languages:\n\tPython\n\tC\n\tJavaScript")
# Languages:
#     Python
#     C
#     JavaScript

Common Escape Sequences

Stripping Whitespace

Stripping Whitespace

REPL Demo

>>> favorite_language = ' python '
>>> favorite_language.rstrip()
' python'
>>> favorite_language.lstrip()
'python '
>>> favorite_language.strip()
'python'
>>> favorite_language
' python '

Which Side Each Method Trims

1

lstrip()

Removes leading (left) whitespace only

2

strip()

Removes whitespace from both ends

3

rstrip()

Removes trailing (right) whitespace only

Practical Use

Cleaning Data in Practice

Example 1 — Login Input Normalization

username = " admin \n"
print(username == "admin")        # False
print(username.strip() == "admin") # True

Without stripping, a trailing newline or leading space causes a string comparison to fail — a common source of authentication bugs.

Example 2 — Removing a URL Prefix (Python 3.9+)

url = "https://ptit.edu.vn"
print(url.removeprefix("https://"))
# ptit.edu.vn

strip() vs removeprefix() — Key Difference

Syntax Errors

Avoiding Syntax Errors with Strings

Incorrect — Apostrophe Inside Single Quotes

message = 'One of Python's strengths is
           its diverse community.'

Traceback

  File "apostrophe.py", line 1
    message = 'One of Python's strengths ...
                            ^
SyntaxError: unterminated string literal

Python interprets the apostrophe in Python's as the closing quote, leaving the rest of the line as unexpected tokens.

Three Fixes

Correct

message = "One of Python's strengths is
           its diverse community."
print(message)
Integers

Integers

REPL Demo

>>> 2 + 3
5
>>> 3 - 2
1
>>> 2 * 3
6
>>> 3 / 2
1.5
>>> 3 ** 2
9
>>> 10 ** 6
1000000
>>> 2 + 3*4
14
>>> (2 + 3) * 4
20

Operator Reference

Security Contexts

Integers in Security Work

Security-Relevant Powers of 2

print(2 ** 16)   # 65536 — TCP/UDP port space (0–65535)
print(2 ** 32)   # 4294967296 — IPv4 address space
print(2 ** 128)  # exact big integer — IPv6 / 128-bit keys

Number Base Literals

print(0xFF, 0b1010, 0o17) # 255  10  15
print(hex(255), bin(10))  # 0xff 0b1010

Hexadecimal (0x), binary (0b), and octal (0o) literals are commonly used in low-level security and networking code.

Arbitrary Precision for Cryptography

Python's arbitrary-precision integers let code handle cryptographic-size numbers natively — no special library needed for basic arithmetic on RSA moduli or large primes.

The built-in pow(base, exp, mod) performs modular exponentiation efficiently — a core operation in RSA and Diffie-Hellman.

pow(2, 100, 1000000007)  # fast modular exp
Floats

Floats

REPL Demo — IEEE 754 Surprise

>>> 0.1 + 0.1
0.2
>>> 2 * 0.1
0.2
>>> 0.2 + 0.1
0.30000000000000004
>>> 3 * 0.1
0.30000000000000004

Floats use IEEE 754 double precision. Some decimal fractions — including 0.1 — cannot be represented exactly in binary, producing small rounding errors.

This occurs in all languages that use IEEE 754, not only Python.

Integers and Floats Together

Integers and Floats

REPL Demo

>>> 4 / 2
2.0
>>> 1 + 2.0
3.0
>>> 2 * 3.0
6.0
>>> 3.0 ** 2
9.0

Type Promotion Rules

Division / always returns a float, even if the result is a whole number.

Mixing int and float in any operation returns a float.

Use // for integer (floor) division: 7 // 2 → 3.

Type Conversion Functions

Integers and Floats Together

Underscores in Numbers

Code

universe_age = 14_000_000_000
print(universe_age)   # 14000000000

MAX_FILE_SIZE = 10_485_760  # 10 MiB in bytes

print(1000 == 1_000 == 10_00)  # True

How It Works

Underscores are purely cosmetic. Python ignores them entirely when storing the numeric value. The grouping can be placed anywhere — the conventional 3-digit grouping matches standard number formatting.

When to Use Underscores

Large Integer Literals

Port ranges, address space sizes, memory sizes — any value where digit grouping aids reading.

Float Literals

Also works for floats: 3.141_592_653 is valid.

Constants

Combine with ALL_CAPS convention (Section 2.3.6) for readable constant definitions.

Available since Python 3.6 (PEP 515).

Multiple Assignment

Multiple Assignment

Code

x, y, z = 0, 0, 0

host, port = "127.0.0.1", 8080
print(host, port)   # 127.0.0.1 8080

a, b = 1, 2
a, b = b, a         # swap without temp variable
print(a, b)         # 2 1

ValueError if Count Mismatches

x, y = 1, 2, 3
# ValueError: too many values to unpack (expected 2)

Practical Uses

Initialize Multiple Variables

x, y, z = 0, 0, 0 is more concise than three separate assignment lines.

Network Connection Parameters

host, port = "127.0.0.1", 8080 — a common pattern in network programming and security tools.

In-place Swap

The swap a, b = b, a is idiomatic Python — no temporary variable is needed because the right side is fully evaluated before assignment.

Constants

Constants

Convention: ALL_CAPS Names

MAX_CONNECTIONS = 5000
DEFAULT_TIMEOUT = 3.0
API_BASE_URL = "https://api.example.com"

Optional: typing.Final (Python 3.8+)

from typing import Final
MAX_LOGIN_ATTEMPTS: Final = 5

Static checkers such as mypy will flag any attempt to reassign a Final name — enforcement happens offline, not at runtime.

Constant Enforcement Comparison

Comments

How to Write Comments

Basic Example

# Say hello to everyone.
print("Hello Python people!")

Output

Hello Python people!

Everything after # on a line is ignored by the interpreter. The comment does not appear in the output.

Comments

What Kind of Comments to Write

Poor Comment — Restates the Code

x = x + 1  # add 1 to x

The comment adds no information beyond what the code already says. A reader who can read Python gains nothing from it.

Good Comment — Explains the Why

# Retry once more because the remote host
# may drop the first SYN under load.
retries = retries + 1

This comment explains the reason for the code — information that cannot be inferred from the syntax alone.

Guidelines (PEP 8)

Explain Why, Not What

The code already describes what happens. Comments should capture the intent, rationale, or approach.

Write While Reasoning Is Fresh

Removing extra comments later is easier than reconstructing missing ones weeks later.

Keep Comments Up to Date

A comment that contradicts the code is worse than no comment — it actively misleads the reader (PEP 8).

Collaborative Code

Most software is written and maintained by teams. Clear comments are expected in professional and open-source projects.

Exercises

Practice Exercises — Chapter 2

01

Simple Message

Assign a message to a variable and print it.

02

Simple Messages

Change the variable's value and print both messages.

03

Personal Message

Store a name; print "Hello Eric, would you like to learn some Python today?"

04

Name Cases

Print a name in lower, upper, and title case.

05

Famous Quote

Print a quote with its author, including quotation marks.

06

Famous Quote 2

Store the author in famous_person and the sentence in message.

01

Stripping Names

Use \t and \n around a name; demonstrate lstrip(), rstrip(), strip().

02

Number Eight

Write four operations using +, -, *, / whose result is 8.

03

Favorite Number

Build and print a message containing a number using an f-string.

04

Adding Comments

Add a header comment and explanatory comments to two earlier programs.

05

Zen of Python

Run import this in the REPL and read the full output.

Session 1 Summary & What's Next

Chapter 1

History, naming, and design principles of Python (PEP 20 — Zen of Python)

Installing Python 3, choosing an editor, REPL vs .py scripts

Running programs from editor and terminal; reading tracebacks

Chapter 2

Variables as labels; naming rules (PEP 8); NameError

Strings: case methods, f-strings, escape sequences, strip, quote handling

Numbers: int (arbitrary precision), float (IEEE 754), //, %, underscores, multiple assignment, constants

Comments: #, docstrings, explain "why" not "what"

Next Session

Chapter 3

Lists — creating, indexing, slicing, modifying

Chapter 4

If Statements — conditional logic and branching

Reference

Eric Matthes, Python Crash Course, 2nd ed., No Starch Press, 2019

Official documentation: docs.python.org/3