Unit 1 (Review and Programming Practice)
Section 1
- Why decimal numbers are natural for humans, and why binary numbers are more natural for computers.
- What is a 0 and a 1 in computer hardware.
- Properties of, and operations with binary numbers.
- The Carry, and the Ripple Effect.
- Review: various types of variables, such as integer (int), real number (float), text string (str), tuple (tuple), list (list), dictionary (dict) etc.
- Review: checking types of variables using the built-in Boolean function isinstance().
- Review: generating random integers using the function randint() from the random library.
- Generating random binary numbers.
- Review: integer division operator // and the modulo operator %.
- Converting decimal numbers to binary and vice versa.
- Addition of decimal and binary integers.
Section 2
- Properties of, and operations with hexadecimal numbers.
- Main applications of hex numbers: represent locations (addresses) in computer memory, MAC (hardware) addresses, and color codes.
- Review: checking whether a given item is present in a list.
- Using the ASCII table to generate hex numbers.
- Converting decimal numbers to hexadecimal and vice versa.
- Hex numbers may contain both lowercase or uppercase characters.
- Special relationship between hexadecimal and binary numbers.
- Converting hex numbers to binary one digit at a time.
- Converting binary numbers to hexadecimal in four-digit chunks.
- Review: using assertions and exceptions to protect functions against flawed input data.
- Sometimes, sanity checks may take more lines than the actual function body.
Section 3
- Transistor count, Moore’s Law, and CPU clock speed.
- Exploring transistors and logic gates.
- Using Python to simulate the seven basic types of logic gates: AND, OR, NOT, NAND, NOR, XOR, and XNOR.
- Practicing safe programming with assertions and exceptions.
Section 4
- Combining logic gates and simulating simple logic circuits in Python.
- Simulating the XOR gate using the AND, OR and NAND gates, as well as using the AND, OR and NOT gates.
- Simulating the Half Adder using the XOR and AND gates.
- Simulating the Full Adder by adjusting the Half-Adder to be stackable.
- Simulating the Two-Bit, Four-Bit and Eight-Bit Adders as arrays of Full Adders.
- Simulating the Full-Adder using the XOR, AND and OR gates.
Section 5
- Various uses of the underscore character _ in Python.
- Role of the so-called “shift” in multiplication.
- Performing multiplication with just addition and shift.
- Simulating the Four-Bit Multiplier using the Eight-Bit Adder.
- Simulating the Eight-Bit Multiplier using the Sixteen-Bit Adder.
- Using the bitwise shift operators <<, >>, <<= and >>= in Python.
Unit 2 (Object-Oriented Programming I)
Section 6
- Brief history of computers and programming languages.
- Importance of using well-designed data structures.
- How did object-oriented programming evolve from procedural programming.
- Main differences between procedural and object-oriented programming.
- Classes consist of data (attributes) and functions (methods).
- An object is an instance of a class.
- A class can have many different instances.
- Instances of a class do not share data.
- Methods are defined on the level of a class but used on the level of an instance.
- All data types in Python are classes.
- The so-called “magic methods” in Python and how they work.
- The bitwise operators & (AND) and | (OR).
Section 7
- Defining new classes using the keyword class.
- Using the constructor __init__() to define class attributes and initialize their values.
- The constructor as well as all class methods must have a mandatory first parameter self.
- All attributes and methods of a class must be accessed through the prefix self.
- Adding new methods and new attributes to a class.
- Instantiating a class.
- It is a good programming practice in OOP to always access class attributes via class methods (not directly).
- Using the Sympy and other Math libraries.
- ‘self’ is not a Python keyword.
- Creating two training classes: Vocabulary and Number.
Section 8
- Defining new classes with the keyword class.
- Using the constructor __init__() to define class attributes and initialize their values.
- Adding new methods and new attributes to a class.
- Instantiating a class.
- Using file operations and working with regular expressions.
- Not every class needs to have attributes.
- A class without attributes does not need a constructor.
- Creating two new classes: Converter and DataMiner.
Section 9
- Implementing class Line to represent lines in the XY plane:
- Attributes: startx, starty, angle, length, lw (line width), color, ls (line style).
- Methods: __init__(), get_endpoint(), set_endpoint(), plot(), get_length(), get_area().
- Making data structures flexible and open to future development, even though this could mean that they require more memory.
- Premature optimization is the root of all evil (or at least most of it) in programming.
- Matplotlib has four different line styles, and how to define them.
- Objects can be stored in lists like any other variables.
Section 10
- Using the class Line as a basis to implement class Turtle, a simplified version of the well known Python Turtle Graphics:
- Attributes: posx, posy, angle, linewidth, linecolor, linestyle, drawing, lines.
- Methods: __init__(), go(), left(), right(), penup(), pendown(), goto(), back(), set_angle(), show(self), width(), color(), style(), get_length(), get_area().
- Practicing working with exceptions.
- Exploring additional useful functions of Matplotlib.
Unit 3 (Object-Oriented Programming II)
Section 11
- Static methods and when they can be useful.
- How to derive a subclass from a superclass.
- When a new subclass should be created, as opposed to modifying the original class.
- If the superclass has attributes, then the constructor of the subclass must call the constructor of the superclass.
- Using the function super() to access the superclass.
- Subclasses can add new attributes and methods, as well as override methods.
- Importance of a well-designed class hierarchy.
- What is polymorphism and when it can be useful.
- What are abstract methods and abstract classes, and when they can be useful.
- Using the abc (Abstract Base Classes) module.
- Using ternary conditional expressions.
Section 12
- Programming practice: Upgrading the Graphics Editor from Python Fundamentals to an object-oriented design (Phase 1).
- Designing a base class Shape with 6 attributes and 20 methods.
- Meaning of single and double underscores in the names of class attributes and methods.
- Review: PEP 8 – Style Guide for Python Code, copying lists via slicing, list comprehension, shallow and deep copying, obtaining memory addresses of Python objects, accessing class attributes via dedicated class methods.
Section 13
- Programming practice: Upgrading the Graphics Editor from Python Fundamentals to an object-oriented design (Phase 2).
- Designing and implementing a hierarchy of classes to represent 10 basic geometric shapes.
- Practicing class creation and inheritance.
Section 14
- Programming practice: Upgrading the Graphics Editor from Python Fundamentals to an object-oriented design (Phase 3).
- Designing and implementing class Figure to represent figures consisting of one or more basic shapes.
- Practicing class creation and inheritance.
Section 15
- Programming practice: Upgrading the Graphics Editor from Python Fundamentals to an object-oriented design (Phase 4).
- Designing and implementing three different classes SimpleDrawing, SmartDrawing, and TechDrawing based on three different use cases.
- Analyzing an example of bad object-oriented programming.
- In OOP, classes should always work with their own attributes, not with the attributes of other classes.
- Multiple inheritance, its applications, and its limitations.
- Multiple inheritance vs. standard inheritance.
- The Diamond Problem and when it represents a real problem.
- Mixin classes.
Unit 4 (Selected Advanced Techniques)
Section 16
- Recursion and its applications.
- Flattening lists.
- Polish (prefix) notation.
- Interactive input.
- Functions eval() and exec().
- Variadic functions.
- Anonymous (lambda) functions.
Section 17
- Various types of tree data structures.
- Using recursion to work with binary trees.
- Iterables and iterators, functions iter() and next().
- Built-in functions any() and all().
- Defining custom iterators from scratch.
- Making iterators via generator functions and generator expressions.
- Applying maps and filters to data, functions map() and filter().
- Using the function reduce() for cumulative operations with iterables.
Section 18
- Using metasyntactic variables.
- Working with names and namespaces.
- Creating modules and packages.
- Using built-in decorators.
- Creating custom decorators.
- Writing decorators with parameters.
- Queuing (chaining) decorators.
- Decorating class methods.
- Making Python classes callable.
- Working with JSON and XML data.
Section 19
- Overview of the Pandas and Seaborn libraries.
- Structure of Pandas DataFrames.
- Entering data into a DataFrame.
- Creating scatter plots, regression plots, and residual plots with Seaborn.
- Using the residual plot to justify the linear regression model.
- Making simple predictions.
Section 20
- Using Pandas to read files from the hard disk or from a URL.
- Obtaining the number of rows and number of columns of a DataFrame.
- Obtaining the list of all column names of a DataFrame.
- Displaying the beginning and the end of a DataFrame.
- Other operations with DataFrames.
- Cleaning data.