Course overview
An introduction to programming and computational thinking with Python: how computers run programs, core syntax and logic, data structures, the real development ecosystem, and numerical/data-oriented programming with NumPy, pandas and Matplotlib. Learning is hands-on and project-oriented, with examples drawn from Computer Science and AI contexts and a final group project.
The course starts with the basics of how code is executed (compiled vs. interpreted) and how to plan with pseudocode, then builds up through functions, scope and data structures, a midterm checkpoint, the developer workflow (CLI, VS Code, environments, OOP), and finishes with array programming, data handling and a final exam. Every concept below is reinforced by the interactive demos in this repo.
Why it matters. Programming is described in the syllabus as "the art and science of designing and writing software that instructs computers to perform tasks" β the foundational skill that underpins everything from reliable software systems to data-driven and intelligent applications. This course assumes little or no prior experience and is the gateway to later BCSAI coursework in algorithms and data structures, data-centric programming, and introductory machine learning. The emphasis throughout is on transfer: habits and patterns learned here are meant to be reused across the rest of the degree.
What you will be able to do. By the end you should be able to build small-to-medium Python programs that automate tasks, process and analyze data, and implement basic algorithmic solutions β writing code that is correct, clear, and easy to maintain, and iterating on it through testing and refinement.
Office hours: on request by email. Tooling: laptop every session; Google Colab notebooks; VS Code as the primary local environment (set up in English).
Learning objectives
By the end of the course, students should be able to:
- Write correct, readable Python to solve structured and open-ended problems from CS and AI contexts.
- Understand and apply core programming concepts: variables, data types, expressions, control flow (conditionals and loops), and functions.
- Design simple algorithms using fundamental data structures β lists, tuples, sets, dictionaries β and basic array-based computation (NumPy).
- Decompose problems into modular components, define clear interfaces, and reuse code through functions and well-structured modules.
- Apply good programming practices: naming, formatting, basic complexity awareness, and code organization.
- Debug systematically by interpreting error messages, using print/debugger workflows, and validating behavior with simple tests.
- Work with the Python development ecosystem: files (text/JSON), libraries, and isolated environments (pip/conda/venv).
- Handle and analyze tabular data with pandas, visualize results with Matplotlib, and export reproducible outputs.
- Translate real-world tasks into programs that automate workflows, process data, and support basic computational experiments relevant to AI.
- Communicate solutions β summarize the problem, explain design decisions, present results clearly.
- Abstraction β identify patterns, generalize solutions, choose appropriate data representations.
- Collaboration in small teams using basic shared-code tooling and version-control workflows.
- Adaptability and independence in learning new tools, libraries, and concepts as technology evolves.
Teaching methodology & workload
Each session pairs concise theory with substantial hands-on practice. New concepts are introduced through short lectures, then reinforced with guided examples and exercises from CS/AI contexts. A flipped-classroom approach is used when appropriate β review readings, videos or notebooks before class so in-person time focuses on discussion, live coding, and problem solving. Learning is supported by three recurring activities: in-class exercises, problem sets, and brief announced quizzes.
- In-class exercises β frequent short tasks during class to build fluency and confidence with core programming patterns; worked individually and in small groups so you practice reasoning about code, debugging, and communicating solutions.
- Problem sets β deeper, more integrative assignments posted on the campus platform, one per module. Work steadily through the term rather than close to exams. Collaboration is encouraged for understanding and discussing approaches, but submissions should reflect individual work. Selected problems are discussed in class and you may volunteer to present a solution (counts toward participation).
- Brief announced quizzes β short quizzes spread through the semester on previously taught material; they help consolidate knowledge and let the instructor monitor progress and adjust pacing.
Flipped classroom: when appropriate, review short readings, videos or notebooks before class so in-person time focuses on discussion, live coding, and problem solving. GenAI policy: generative-AI tools may be used for specific tasks with acknowledgment; inappropriate or unacknowledged use is academic misconduct and may mean failing the assignment or the course. A suggested acknowledgment format (AI system, prompts used, how the output was used) is provided in the syllabus.
Assessment
Continuous evaluation across four components. A minimum of 3.5/10 on the final exam is required to pass the course overall, even if other components are passed.
- Final exam Β· 50% β comprehensive, covering all Modules 1β4. Deliverable: a sit-down exam (characteristics announced at the start of the semester). Pass rule: you must score at least 3.5/10 on the final exam to pass the course overall, even if every other component is passed.
- Quizzes + Midterm Β· 25% β several small announced quizzes through the term plus the midterm exam (Modules 1β2), which serves as a checkpoint on foundational understanding and problem-solving skill.
- Group project Β· 15% β done jointly with Linear Algebra, applying programming to that area. Must be completed and submitted before the final exam and includes an in-person presentation. Evaluation: correctness, code quality, appropriate use of course tools, reproducibility, and presentation clarity β assessing both group collaboration and individual contribution.
- Class participation Β· 10% β active engagement in lectures (questions, remarks, volunteering problem-set solutions). Graded on punctuality, participation, and conduct; disruptions or excessive talking may incur a penalty.
Attendance & re-sit: 80% attendance is required β falling below it means failing both the ordinary and extraordinary (June/July) calls and re-enrolling next year. A student has four chances across two academic years. The June/July re-sit is a single comprehensive exam (continuous evaluation is not carried over), capped at 8.0/10 ("notable"); the 3rd-call retake exam is capped at 10.0. Grade appeals require attending the exam review session first.
Program β full session-by-session structure
All 30 live in-person sessions, grouped by module. Each item lists its session number, title, focus, topics, and key readings/tools, cross-linked to the matching interactive demo where one exists.
Computing basics, compiled vs. interpreted languages, and pseudocode to plan solutions. Students then learn core Python syntax and logic β variables and types, if/else and boolean logic, loops, and basic debugging β before moving into functions, scope, and an introduction to generators plus functional tools.
- Explain how a program runs on the CPU/memory and contrast compiled vs. interpreted execution.
- Plan logic in pseudocode and translate it into correct Python with variables, types and operators.
- Control program flow with conditionals and loops, and read tracebacks to debug systematically.
- Decompose problems into functions β parameters, return values, docstrings, recursion β and reason about scope, generators and basic functional tools.
How a computer actually runs a program, and how to plan logic before writing code.
- The hardware/software interface β the CPU executes instructions while memory (RAM) holds data and code; a "program" is just an ordered set of instructions the machine carries out.
- How programs run: a compiler (e.g. C) translates the whole program to machine code ahead of time, while an interpreter (e.g. Python) executes it line by line β trading raw speed for flexibility and faster iteration.
- Pseudocode β expressing the steps of a solution in plain structured language before writing real code, so logic can be reasoned about independently of syntax.
Key idea: code is a precise plan a machine follows literally. Plan in pseudocode first, then translate to Python β read n β if n > 0 print "positive".
First contact with Python and Colab; variables and basic operations.
- Python and Google Colab β a browser-based notebook (no install) where code runs in cells and results appear inline; the course's everyday scratchpad.
- Variables bind a name to a value of a type:
int/floatfor numbers,boolfor true/false,strfor text. - Arithmetic operators
+ - * /plus integer division//, modulo%and power**. - String methods (
.upper(),.split(), slicing, f-strings) for basic text processing.
Key idea: a variable is a label for a value; the value's type decides which operations are valid ("3" + "4" concatenates, 3 + 4 adds).
Branching with conditionals and boolean logic.
if/elif/elseβ run different blocks depending on whether a boolean condition isTrue; indentation defines what belongs to each branch.- Logical operators
and,or,notcombine conditions; Python evaluates them with short-circuit behavior (stops as soon as the result is known).
Key idea: a conditional chooses a path based on a boolean test β if score >= 5 and attended: passed = True.
Iteration, loop control, and reading errors.
forloops iterate over a known collection;whileloops repeat until a condition becomes false.breakexits early,continueskips to the next iteration.- Combining loops with conditionals to express algorithms (filtering, searching, accumulating).
- Basic debugging β
print()to inspect values mid-run, and reading a traceback bottom-up to find the failing line and exception type.
Key idea: a loop repeats work; the trick is a correct stopping condition. while x > 1: x = x // 2 halves x until it reaches 1.
Modularity: defining and calling functions.
- A function is a named, reusable block that takes inputs and produces an output β the unit of modularity that keeps programs DRY (don't repeat yourself) and testable.
- Defining functions with
def name(params):and a body; calling them transfers control, runs the body, and comes back. - Positional arguments matched by order;
returnhands a value back to the caller (a function with noreturnyieldsNone). - Keyword arguments passed by name and default values that make parameters optional.
Key idea: name a computation once, reuse it everywhere β def area(w, h=1): return w * h.
Documentation, recursion, and testing functions.
- Docstrings (
"""...""") document what a function does; type hints (def f(x: int) -> int) state expected types β both aid readability and maintainability. - Recursion β a function that calls itself on a smaller subproblem until a base case stops the descent (e.g. factorial, tree traversal).
- Debugging functions by tracing inputs/outputs and writing minimal tests that pin down expected behavior.
Key idea: every recursion needs a base case + a step toward it β def fact(n): return 1 if n <= 1 else n * fact(n-1).
Scope, generators, and functional-programming basics.
- Scope (LEGB: Local β Enclosing β Global β Built-in) governs where a name is visible and how long it lives; uncontrolled side effects on global state make code hard to reason about.
- Generators use
yieldto produce values one at a time (lazy evaluation), so you can stream huge or infinite sequences without holding them all in memory. - Functional tools β anonymous
lambdafunctions, plusmap(transform) andfilter(select) β apply a function across a sequence declaratively.
Key idea: lazy & functional style processes data as a pipeline β list(map(lambda x: x*x, filter(lambda x: x>0, nums))).
Working with Python's core data structures β lists/tuples, sets, and dictionaries β practicing iterating, indexing, and building structures efficiently. Covers mutability and side effects in functions, and concludes with an exercise-based review and a midterm exam over Modules 1β2.
- Choose the right container β list, tuple, set, dictionary β based on its properties and cost.
- Iterate, index and slice sequences, and build structures concisely with list comprehensions.
- Use sets for deduplication and fast membership, and dictionaries as hash maps for key/value lookup.
- Predict how mutability lets functions change shared data, and design safer "in-place vs. return-new" APIs.
Introducing the four core containers and how to iterate/index them.
- The four core containers: list (ordered, mutable), tuple (ordered, immutable), set (unordered, unique), dict (keyβvalue) β each picked for different access patterns.
- Iterables β lists and tuples can be walked element by element with a
forloop. - Indexing retrieves an element by position (
xs[0], negative indices from the end) and slicing takes sub-sequences (xs[1:3]). - Initializing containers and mutating their contents (
.append(), item assignment). - List comprehensions β a compact
[expr for x in xs if cond]form to build a new list in one line.
Key idea: pick the container by behavior, not habit. squares = [x*x for x in range(10)] replaces a whole loop.
Sets and the operations they make cheap.
- A set stores unique, unordered elements; backed by a hash table it gives near-O(1) membership tests and supports union/intersection/difference.
- Lists vs. tuples vs. sets β when order and duplicates matter vs. when uniqueness/fast lookup matter; converting with
set(),list(),tuple(). - Operating with sets: deduplication (
set(xs)), membership (x in s), and filtering against a reference set.
Key idea: checking membership in a set is far cheaper than scanning a list β set(a) & set(b) gives shared items instantly.
Key/value storage and how dictionaries are built.
- A dictionary maps unique keys to values; it is Python's hash map, giving fast lookup, insertion and deletion by key.
- Accessing (
d[k],d.get(k)), adding/updating (d[k] = v) and removing (del,.pop()) entries; iterating.keys(),.values(),.items(). - Building dicts from other structures β e.g.
dict(zip(keys, values))or a dict comprehension.
Key idea: dictionaries trade memory for speed: counts[word] = counts.get(word, 0) + 1 tallies items in one pass.
Accumulating data structures iteratively in real contexts.
- The accumulator pattern β initialize an empty container before a loop, then update it each iteration (build a list, tally a dict, grow a set).
- Applied to CS & AI tasks: counting tokens, grouping records, building a frequency table or adjacency map.
Key idea: "empty container + loop that fills it" is the workhorse pattern for turning raw data into structured results.
How functions can change data, and how to write safer APIs.
- Mutability & aliasing β arguments are passed by reference, so a function that mutates a list/dict changes the caller's object too (a common source of bugs).
- Designing safer APIs: decide deliberately between modify-in-place (returns
None, likelist.sort()) and return-a-new-object (leaves the input untouched, likesorted()).
Key idea: mutable defaults & shared references bite. sorted(xs) is safe; xs.sort() rewrites the original in place.
Consolidation through applied exercises.
- Integrative review of Modules 1β2 by solving exercises end to end (logic + functions + data structures).
- Worked CS & AI applications that combine several concepts at once.
- Group challenge β be the first team to solve the set, practicing collaboration and communication under time pressure.
Key idea: fluency comes from combining primitives; review targets the seams where flow control, functions and containers meet.
Exam preparation with a mock.
- Targeted review for the midterm (Modules 1β2), clarifying frequent misconceptions.
- A mock exam drawn from previous years to rehearse format and timing.
Key idea: a timed mock surfaces gaps cheaply β practice under exam conditions before it counts.
Checkpoint on foundational understanding and problem-solving.
- Scope: Modules 1 and 2 β computing basics, control flow, functions, scope, and the core data structures.
- Counts toward the Quizzes + Midterm component (25% of the course grade).
Key idea: a midterm checkpoint signals whether the foundations are solid enough to build the ecosystem and array work on top.
Practical development workflow: the command line and VS Code, notebooks in VS Code, and running programs locally. Students learn to write and execute scripts, organize code into modules and imports, and manage environments and dependencies (conda/pip), with a short introduction to object-oriented programming.
- Navigate the terminal and run Python from both the CLI and an IDE (VS Code).
- Organize code into scripts, modules and imports with a clean
if __name__ == "__main__"entry point. - Create and manage isolated environments and install dependencies with pip/Conda for reproducibility.
- Contrast procedural, functional and object-oriented paradigms and write a small class with attributes and methods.
Moving from notebooks to a real local development environment.
- The command line (CLI) β navigating folders and running programs by typing commands (
cd,ls,python file.py) instead of clicking. - IDEs compared β PyCharm, Spyder, VS Code; what an editor + integrated terminal + debugger buys you over a bare notebook.
- Installing and configuring VS Code (in English) as the course's primary local environment.
- Two ways to run code β from the terminal vs. the editor UI β and using Jupyter notebooks inside VS Code.
Key idea: the terminal is the universal control surface for development; python script.py is the same everywhere.
Structuring real programs across files.
- Writing scripts β standalone
.pyfiles that run top to bottom, unlike cell-by-cell notebooks. - Execution order and the
if __name__ == "__main__":guard β separating reusable definitions from code that should only run when the file is executed directly. - Reusing code by importing functions from one module into another (
from utils import clean).
Key idea: split code into modules of related functions and import them; the __main__ guard keeps a file usable as both a script and a library.
Isolating and reproducing project environments.
- Virtual environments β an isolated per-project Python with its own packages, so one project's dependencies never clash with another's.
- Creating and activating environments with Conda (and the idea of
venv). - Installing libraries with
pip installandconda install; capturing them so a project is reproducible on another machine.
Key idea: "works on my machine" is solved by isolating dependencies per project β conda create -n proj python=3.11.
Comparing paradigms and the basics of classes.
- Paradigms β procedural (steps), functional (transform data via functions), and object-oriented (bundle data with the behavior that acts on it); each suits different problems.
- Why OOP: abstraction (hide detail), encapsulation (keep state with its methods), and cleaner organization as systems grow.
- Classes & objects β a class is a blueprint; an object is an instance with attributes (data) and methods (functions), defined via
__init__andself. - Coding a mini OOP example end to end.
Key idea: a class bundles state with behavior β class Dog: def __init__(self, name): self.name = name; then Dog("Rex").name.
Numerical and data-oriented programming with NumPy. Introduces file/data handling, pandas for tabular data, and Matplotlib for visualization and exporting results, leading into the project wrap-up and final review.
- Use the NumPy ndarray as the core scientific data type β create, index, slice and reshape arrays.
- Compute with vectorized, broadcast operations instead of Python loops, and explain why it is faster.
- Read and write data from disk (text, CSV, JSON) and compute descriptive statistics for ML prep.
- Clean and aggregate tabular data with pandas, visualize it with Matplotlib, and export reproducible outputs.
The array as the core scientific-computing data type.
- NumPy β the foundation of Python scientific computing; its
ndarraystores numbers in a contiguous, typed block for fast bulk math. - Creating arrays (
np.array,np.zeros,np.arange,np.linspace) and inspecting.shape/.dtype. - Indexing and slicing β like lists but extended to multiple dimensions and boolean/fancy indexing.
Key idea: an ndarray is a fixed-type grid of numbers; that uniformity is what makes vectorized math fast β np.arange(6).reshape(2, 3).
Element-wise computation and broadcasting.
- Element-wise arithmetic β
a + b,a * 2apply across the whole array at once, no explicit loop. - Broadcasting β NumPy's rules for combining arrays of different but compatible shapes (e.g. adding a row vector to every row of a matrix).
- Built-in ufuncs and aggregations (
np.sqrt,np.sum,np.mean, axis arguments).
Key idea: broadcasting stretches shapes so operations "just work" β matrix - matrix.mean(axis=0) centers each column.
Reshaping data to fit different computations.
- Reshaping reinterprets the same data in a new shape (
reshape,ravel) without copying when possible. - Joining (
concatenate,stack) and splitting (split) arrays to assemble or break apart datasets. - Adding/removing dimensions (
newaxis,transpose) to make shapes line up for an operation.
Key idea: the same numbers can wear many shapes; getting shapes right is half of array programming β x.reshape(-1, 1) makes a column.
Reading and writing data to and from disk.
- Paths β relative (from the current folder) vs. absolute (from the root); opening files with
with open(...) as f:so they close automatically. - CSV (flat tabular rows) vs. JSON (nested key/value) β what each is good for and when to choose it.
- Loading/saving arrays with NumPy (
np.loadtxt,np.save/np.load).
Key idea: programs are useful when they persist results; with open("out.csv", "w") as f: guarantees the file is flushed and closed.
Summarizing data and preparing it for ML.
- Descriptive statistics β mean, median and standard deviation summarize a dataset's center and spread (
np.mean,np.std). - Correlation & covariance measure how two variables move together β a first look at relationships in data.
- Normalization/scaling (e.g. z-scoring) puts features on a comparable scale, a standard preprocessing step before machine learning.
Key idea: scaling makes features comparable for ML β z = (x - x.mean()) / x.std() gives mean 0, std 1.
Why vectorized code is fast, with a competitive challenge.
- Vectorization β replacing Python loops with array operations that run in optimized C under the hood, often 10β100Γ faster; first awareness of complexity/performance.
- Group challenge β be the team with the fastest correct solution, learning to profile and rewrite hot loops as array ops.
Key idea: let NumPy do the loop in C β (a * b).sum() beats a Python for dot-product by a wide margin.
Tabular data with the pandas DataFrame.
- Series (one labeled column) vs. DataFrame (a labeled table); reading/writing CSV with
pd.read_csv/.to_csv. - Selecting and filtering rows/columns (
.loc,.iloc, boolean masks), creating/transforming columns, and basic cleaning (missing values, types). - GroupBy + aggregation β the split-apply-combine pattern to summarize data per category.
Key idea: pandas is the spreadsheet you program β df.groupby("class")["score"].mean() summarizes in one line.
Turning results into figures and exporting outputs.
- Plotting with Matplotlib β the figure/axes model and basic
plt.plot/plt.scattercalls. - Choosing the right chart β scatter for relationships, line for trends, histogram for distributions, bar for categories.
- Exporting reproducible outputs: saving figures (
savefig) and final datasets to disk.
Key idea: the plot type should match the question; an honest figure plus a saved dataset makes results reproducible.
Group project showcase.
- In-person presentations of the group projects (a CS/AI- or data-analysis-oriented objective), done in collaboration with Linear Algebra.
- Assessed on correctness, code quality, reproducibility, presentation clarity, and individual contribution.
Key idea: communicating a solution clearly is part of engineering β the presentation is graded alongside the code.
Comprehensive preparation for the final exam.
- Cumulative review across all four modules, reconnecting fundamentals, data structures, the ecosystem, and array/data work.
- A full mock exam based on previous years to rehearse scope and pacing.
Key idea: the final rewards integration β revisit how each module's tools combine on a single realistic problem.
Comprehensive assessment of the whole course.
- Scope: all Modules 1β4 β from computing basics through functions, data structures, the Python ecosystem, and NumPy/pandas/Matplotlib.
- Worth 50% of the course; a minimum of 3.5/10 here is required to pass overall, regardless of other components.
Key idea: the final is the gate β strong continuous work still requires clearing the 3.5/10 floor on this exam.
Key concepts β glossary
A quick reference to the recurring terms used across the program. One- or two-line definitions in the course's own context.
- Compiled vs. interpreted
- Compiled languages (C) translate to machine code ahead of time; interpreted ones (Python) execute line by line, trading speed for flexibility.
- Pseudocode
- Plain structured description of an algorithm's steps, written before real code to reason about logic independent of syntax.
- Variable & type
- A name bound to a value; the value's type (
int,float,bool,str) determines valid operations. - Conditional
- An
if/elif/elsebranch that runs different code depending on a boolean test. - Loop
- Repeated execution β
forover a collection,whileuntil a condition fails; controlled bybreak/continue. - Traceback
- Python's error report; read bottom-up to find the exception type and the line that raised it.
- Function
- A named, reusable block taking inputs and returning a value β the basic unit of modular, testable code.
- Docstring / type hint
- In-code documentation (
"""...""") and declared parameter/return types that improve readability and maintainability. - Recursion
- A function that calls itself on a smaller subproblem, bottoming out at a base case.
- Scope (LEGB)
- Where a name is visible: Local, Enclosing, Global, Built-in β resolved in that order.
- Generator / lazy evaluation
- A function using
yieldto produce values on demand, avoiding holding a whole sequence in memory. - Functional tools
lambda,mapandfilterβ apply or select with functions over a sequence declaratively.- List / tuple
- Ordered sequences; lists are mutable, tuples immutable. Indexed and sliced by position.
- List comprehension
- A compact
[expr for x in xs if cond]expression that builds a new list. - Set
- Unordered collection of unique items giving fast membership tests and set algebra (union/intersection).
- Dictionary (hash map)
- A keyβvalue store with fast lookup, insertion and deletion by key.
- Mutability & side effect
- Whether an object can change in place; functions mutating shared objects cause side effects visible to the caller.
- Module / import
- A
.pyfile of reusable definitions brought into another file withimport. - Virtual environment
- An isolated per-project Python with its own packages (Conda/venv) for reproducibility.
- Class / object
- A class is a blueprint bundling attributes (data) and methods (behavior); an object is an instance of it.
- ndarray (NumPy)
- A contiguous, fixed-type, N-dimensional array β the core data type for fast numerical computing.
- Vectorization
- Expressing computation as whole-array operations instead of Python loops, running in optimized C.
- Broadcasting
- NumPy rules that let arrays of compatible-but-different shapes combine element-wise without manual reshaping.
- DataFrame (pandas)
- A labeled, spreadsheet-like table; the unit for cleaning, filtering and group-by aggregation.
- Normalization / scaling
- Rescaling features (e.g. z-score) to a comparable range as preparation for machine learning.
Annotated bibliography & tools
Core references and the tooling used throughout the course, each with a one-line note and the sessions where it is most relevant. The official syllabus does not prescribe a single textbook; the items below are the standard documentation and widely used companions for the topics covered.
- The Python Tutorial & Language Reference (docs.python.org) β the authoritative source for syntax, types, functions and the standard library. Sessions 2β19
- Google Colab β zero-install browser notebooks; the everyday environment for early exercises. Sessions 2β15
- "Automate the Boring Stuff with Python" (Sweigart) β beginner-friendly take on scripts, files and practical automation. Sessions 1β7, 17, 23
- "Think Python" (Downey) β clear treatment of variables, control flow, functions, recursion and scope. Sessions 1β7
- Python
collections& data-model docs β reference for lists, tuples, sets, dicts and their methods. Sessions 8β12 - VS Code documentation β installing, running, and debugging Python locally; integrated terminal and notebooks. Sessions 16β17
- Conda / pip user guides β creating environments and installing dependencies reproducibly. Session 18
- NumPy documentation (Absolute Beginner's Guide) β arrays, indexing, broadcasting and vectorized operations. Sessions 20β25
- pandas documentation ("10 minutes to pandas") β Series/DataFrame, I/O, filtering, cleaning and group-by. Session 26
- Matplotlib documentation (Pyplot tutorial) β building, choosing and exporting figures. Session 27
- Interactive demos in this repo β runnable visualizations of execution, flow, recursion, scope, hashing, mutability and vectorization. cross-linked per session