Python Programming for Beginners Guide
Python Programming for Beginners Guide
Definition: The way of the program is the mindset that combines mathematical formalism,
engineering design, and scientific experimentation to solve problems with computers.
Problem solving is the core skill: formulate the problem, devise creative solutions, and
express them clearly.
Learning to program provides a concrete arena for practicing these skills.
Why Python?
Fun, productive, and easy to start – students can write “neat things” right away.
Portable across Linux, Windows, macOS.
Free and open‑source; aligns with the GNU Free Documentation License.
Quote: “A compiler translates a program once, producing an executable that can run repeatedly
without further translation. An interpreter reads and executes the program incrementally.”
$ python
>>> print 1 + 1
2
# file: [Link]
print(1 + 1)
Execute:
$ python [Link]
2
#include <iostream.h>
void main() {
cout << "Hello, world." << endl;
}
print("Hello, World!")
Observation: The Python example eliminates 13 paragraphs of C++ syntax explanation, letting
students focus on the concept of a program statement.
Quote: “In Python a variable is a name that refers to a thing,” mirroring the mathematical notion of
a variable.
📊 Summary Tables
Comparison: Python vs. C++ for Beginners
Feature Python C++
Syntax complexity Minimal; easy to read Verbose; many keywords
(#include, void, ;)
Setup No compilation; run directly Requires compilation, linking
Learning curve Low; immediate results Steeper; low‑level details can
intimidate
Standard library Large, ready‑to‑use modules Smaller, more fragmented
Teaching focus Concepts first, details later Often forced to cover low‑level
details early
End of notes for the introductory portion of “How to Think Like a Computer Scientist.”## 🖥️ What Is a
Program?
The basic instruction types that appear in almost every language are:
Instruction Description
Input Get data from keyboard, file, or other device
Output Display data on screen or write to a file/device
Math Perform arithmetic (e.g., addition, multiplication)
Conditional execution Execute a block only if a condition holds
Repetition Perform an action repeatedly (loops)
Programming = breaking a large task into smaller subtasks that can be expressed with these primitives.
🐞 Debugging
Debugging is the process of finding and fixing errors (bugs) in a program.
Key differences:
Aspect Natural Language Formal Language
Ambiguity Common, resolved by context Designed to be (nearly)
unambiguous
Redundancy High (verbose) Low (concise)
Literalness Uses idiom, metaphor Means exactly what it says
Parsing Done subconsciously Explicit parsing required
Parsing
Variable Assignment
The variable name appears on the left, the value on the right.
Variable names must start with a letter, may contain letters, digits, and underscores (_).
Keywords (e.g., class, def, if) cannot be used as variable names.
Illegal example Reason
76trombones = "big parade" Starts with a digit
more$ = 1000000 Contains illegal $ character
class = "CS 101" class is a keyword
🧩 Statements
Statement type Effect
Print Displays a value (print(message))
Assignment Binds a name to a value (x = 5)
Multiple statements in a script execute sequentially, producing output as each statement finishes.
📚 Operations on Strings
+ → concatenation
* → repetition (string × integer)
fruit = "banana"
bakedGood = " nut bread"
print(fruit + bakedGood) # banana nut bread
print("Fun"*3) # FunFunFun
🧱 Composition
Expressions can be nested inside other statements:
print(17 + 3) # prints 20
print("Minutes:", hour*60+minute) # combines arithmetic with print
percentage = (minute * 100) / 60 # expression on RHS of assignment
📞 Functions
3.1 Function Calls
>>> type("32")
<class 'str'>
>>> betty = type("32")
>>> print(betty)
<class 'str'>
Syntax: function_name(argument).
The argument is the value supplied; the return value is what the function produces.
>>> int("32")
32
>>> int(3.999)
3
>>> float("3.14159")
3.14159
>>> str(32)
'32'
>>> minute = 59
>>> minute / 60.0
0.983333333333
import math
decibel = math.log10(17.0)
angle = 1.5
height = [Link](angle)
def newLine():
print()
def threeLines():
newLine()
newLine()
newLine()
def printTwice(bruce):
print(bruce, bruce)
printTwice('Spam') # Spam Spam
printTwice(5) # 5 5
Parameter names are local to the function; they need not match the argument variable
names.
__main__
chant1 -> "Pie Jesu domine,"
chant2 -> "Dona eis requiem."
catTwice
part1 -> "Pie Jesu domine,"
part2 -> "Dona eis requiem."
cat -> "Pie Jesu domine, Dona eis requiem."
printTwice
bruce -> "Pie Jesu domine, Dona eis requiem."
3.10 Recursion
A function may call itself.
def countdown(n):
if n == 0:
print("Blastoff!")
else:
print(n)
countdown(n-1)
Base case – condition that stops further recursive calls (n == 0).
Recursive case – calls the same function with a simpler argument (n-1).
Infinite recursion occurs when no base case is reachable, leading to a RuntimeError: maximum
recursion depth exceeded.
🔀 Conditionals
4.1 Modulus Operator
>>> remainder = 7 % 3
>>> print(remainder)
1
4.4 if Statements
if x > 0:
print("x is positive")
if x % 2 == 0:
print(x, "is even")
else:
print(x, "is odd")
if x < y:
print("x < y")
elif x > y:
print("x > y")
else:
print("x == y")
if x == y:
print("equal")
else:
if x < y:
print("x < y")
else:
print("x > y")
def printLogarithm(x):
if x <= 0:
print("Positive numbers only, please.")
return
result = [Link](x)
print("log =", result)
return ends the function early; optional value after return becomes the function’s result.
def nLines(n):
if n > 0:
print()
nLines(n-1)
🎯 Key Takeaways
1. Programs consist of basic instructions (input, output, math, condition, repetition).
2. Debugging follows a systematic, experimental approach.
3. Formal languages require precise syntax and semantics; parsing is essential.
4. Variables bind names to values of specific types; naming rules avoid keywords.
5. Expressions obey operator precedence (PEMDAS) and can be composed.
6. Functions enable reuse, modularity, and recursion; they may return values.
7. Conditionals (if, elif, else) control execution flow; logical operators simplify complex tests.
8. Recursion must have a clear base case to avoid infinite loops.
9. User input is obtained via raw_input; always convert to the desired type.
These notes can be combined with other sections to build a complete study guide for introductory
🟢
Python programming.## Boolean Functions
Boolean functions return True or False, useful for hiding complex tests.
Example (concise form):
if isDivisible(x, y):
print("x is divisible by y")
else:
print("x is not divisible by y")
🔁 Recursion
Recursion expresses a definition that references itself.
Factorial (n!) definition:
n Definition
0 $\mathbb{1}$
$n>0$ $n \times (n-1)!$
Python implementation (step‑by‑step):
def factorial(n):
if n == 0:
return 1
else:
recurse = factorial(n-1)
result = n * recurse
return result
Leap of Faith: When encountering a recursive call, assume the call works correctly and
focus on how the current call combines that result.
📈 Fibonacci
Mathematical definition:
n Formula
0 $\mathbb{1}$
1 $\mathbb{1}$
$n\ge 2$ $F(n-1) + F(n-2)$
Python version (uses leap of faith):
def fibonacci(n):
if n == 0 or n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
Guardians (first two if statements) protect the recursive logic from invalid inputs.
Other terms:
Temporary variable: Holds intermediate results.
Dead code: Never executed (e.g., after a return).
None: Default return value when no return is given.
Incremental development: Build and test small pieces step‑by‑step.
Guardian: Input‑validation checks that protect the core algorithm.
🔄 Iteration
Repeating tasks without errors → use loops (while, for).
🔁 While Loop
def countdown(n):
while n > 0:
print(n)
n = n - 1
print("Blastoff!")
Flow:
1. Evaluate condition.
2. If false → exit loop.
3. If true → execute body, then return to step 1.
📋 Generating Tables
x = 1.0
while x < 10.0:
print(x, '\t', [Link](x))
x = x + 1.0
def printMultTable():
i = 1
while i <= 6:
printMultiples(i)
i = i + 1
def printMultTable(high):
i = 1
while i <= high:
printMultiples(i, high)
i = i + 1
📦 Functions Overview
Naming convention: use descriptive, often yes/no style for booleans (isDivisible).
Benefits:
1. Improves readability.
2. Enables modular debugging.
3. Supports recursion and iteration.
4. Promotes code reuse.
Length
# while version
index = 0
while index < len(fruit):
print(fruit[index])
index = index + 1
String Slices
s = "Peter, Paul, and Mary"
print(s[0:5]) # 'Peter'
print(s[7:11]) # 'Paul'
print(s[17:21]) # 'Mary'
Omit start → start at 0; omit end → go to end; s[:] copies the whole string.
Comparison
if word == "banana":
...
if word < "banana":
...
Uppercase letters sort before lowercase; convert to a common case ([Link]()) for
case‑insensitive comparison.
Immutability
Strings cannot be changed in place:
greeting = "Hello"
# greeting[0] = 'J' # TypeError
newGreeting = 'J' + greeting[1:]
Find Function
Counting Characters
import string
index = [Link]("banana", "a") # = 1
lowercase = [Link] # all lowercase letters
uppercase = [Link]
digits = [Link]
whitespace = [Link]
Character Classification
def isLower(ch):
return ch in [Link] # or: return 'a' <= ch <= 'z'
📚 Lists
Created with brackets: mylist = [1, 2, 3] or via range().
Access: mylist[0], supports negative indices.
for i in range(len(mylist)):
print(mylist[i])
# or simply
for item in mylist:
print(item)
Membership
List Operations
Operator Meaning
+ Concatenate two lists
* Repeat list N times
Slices
lst = ['a','b','c','d','e','f']
print(lst[1:3]) # ['b','c']
print(lst[:4]) # ['a','b','c','d']
print(lst[3:]) # ['d','e','f']
Mutability
Deletion (del)
List Parameters
Passing a list to a function passes a reference (alias), not a copy.
def deleteHead(lst):
del lst[0]
numbers = [1,2,3]
deleteHead(numbers) # numbers becomes [2,3]
import string
words = [Link]("The rain in Spain...")
joined = [Link](words) # 'The rain in Spain...'
joined_underscore = [Link](words, '_') # 'The_rain_in_Spain...'
🧩 Tuples
Immutable ordered collections, defined with commas (parentheses optional).
t = (1, 2, 3)
single = ('a',) # note trailing comma
a, b = b, a
Returning Tuples
a, b = swap(a, b)
Caution: A function that attempts x, y = y, x inside does not affect the caller’s variables
(semantic error).
Random Numbers
import random
x = [Link]() # float in [0.0, 1.0)
📖 Glossaries (selected)
Compound data type: A type whose values consist of multiple components (e.g., strings, lists,
tuples).
Clone: Creating a new object with the same value (new = old[:] for lists).
Leap of Faith: Assuming a recursive call works correctly to reason about the surrounding code.
Histogram: List of counts representing how many values fall into each bucket. ## 📦 Compound
Types
🔢 Tuples
“A sequence type similar to a list but immutable.”
📚 Dictionaries
“A collection of key‑value pairs that maps immutable keys to any values.”
📖 Dictionary Operations
Operation Syntax Effect
Create empty eng2sp = {} New empty dictionary
Add/Update eng2sp['one'] = 'uno' Insert or change entry
Delete del inventory['pears'] Remove entry
Length len(dict) Number of key‑value pairs
Access dict[key] Retrieve value (KeyError if
missing)
🛠️ Dictionary Methods
Method Call Returns
keys [Link]() List of keys
values [Link]() List of values
items [Link]() List of (key, value) tuples
has_key d.has_key(k) True/False (key present)
get [Link](k, default) Value or default if missing
🗂️ Sparse Matrices
List‑of‑lists stores many zeros.
Dictionary representation stores only non‑zero entries:
previous = {0: 1, 1: 1}
def fibonacci(n):
if previous.has_key(n):
return previous[n]
new = fibonacci(n-1) + fibonacci(n-2)
previous[n] = new
return new
🔢 Long Integers
Python automatically promotes to long when an integer overflows.
Create explicitly with 1L or long():
letterCounts = {}
for letter in "Mississippi":
letterCounts[letter] = [Link](letter, 0) + 1
# Result: {'M':1, 'i':4, 's':4, 'p':2}
items = [Link]()
[Link]()
print(items) # [('M', 1), ('i', 4), ('p', 2), ('s', 4)]
📂 Files
📖 Opening, Reading, Writing
f = open("[Link]", "w") # write mode, creates or truncates file
[Link]("Now is the time")
[Link]()
🗂️ Directories
Specify full path: open("/usr/share/dict/words", "r").
/ is a directory separator, not part of a filename.
🥒 Pickling (Serialization)
import pickle
f = open("[Link]", "wb")
[Link](12.3, f)
[Link]([1, 2, 3], f)
[Link]()
f = open("[Link]", "rb")
x = [Link](f) # 12.3 (float)
y = [Link](f) # [1, 2, 3] (list)
[Link]()
⚠️ Exceptions
Exception Cause
ZeroDivisionError Division by zero
IndexError Invalid list index
KeyError Missing dict key
IOError File operation failure
Handle with try/except:
try:
f = open(filename, "r")
except IOError:
print("No such file:", filename)
def inputNumber():
x = input("Pick a number: ")
if x == 17:
raise ValueError, "17 is a bad number"
return x
p = Point()
p.x = 3.0
p.y = 4.0
box = Rectangle()
[Link] = 100.0
[Link] = 200.0
[Link] = Point()
[Link].x = 0.0
[Link].y = 0.0
🔁 Instances as Arguments
def printPoint(p):
print('(' + str(p.x) + ', ' + str(p.y) + ')')
🤝 Sameness (Equality)
== compares references (shallow equality).
Deep equality requires explicit comparison:
📋 Copying Objects
Method Result Notes
[Link](obj) Shallow copy Copies top‑level container,
shares nested objects
[Link](obj) Deep copy Recursively copies all
embedded objects
import copy
p2 = [Link](p1) # independent copy
⏰ Time Class
class Time:
def __init__(self, hours=0, minutes=0, seconds=0):
[Link] = hours
[Link] = minutes
[Link] = seconds
def convertToSeconds(t):
return ([Link] * 60 + [Link]) * 60 + [Link]
def makeTime(seconds):
time = Time()
[Link] = seconds // 3600
[Link] = (seconds % 3600) // 60
[Link] = seconds % 60
return time
📈 Algorithmic Insight
Treat a Time as a base‑60 number:
$\text{total seconds}=3600\cdot h + 60\cdot m + s$
Conversion to/from seconds simplifies arithmetic and avoids manual carries.
class Point:
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __str__(self):
return '(' + str(self.x) + ', ' + str(self.y) + ')'
🃏 Card Objects
class Card:
suitList = ["Clubs", "Diamonds", "Hearts", "Spades"]
rankList = ["narf", "Ace", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "Jack", "Queen", "King"]
def __str__(self):
return [Link][[Link]] + " of " + [Link][[Link]]
Key Takeaways
Use mutable types for data that changes; immutable types for stable keys.
Dictionaries provide fast key‑based lookup; remember they are unordered.
When dealing with large, sparse data, prefer a dictionary keyed by coordinates.
Memoization (hints) dramatically improves recursive algorithm performance.
Python automatically handles integer overflow via long integers.
File I/O follows the open‑read/write‑close pattern; pickle preserves object types.
Understand aliasing vs copying to avoid unintended side effects.
Design classes with __init__ and __str__; overload operators for natural syntax.
Polymorphic functions work on any type that satisfies the required operations.## Card 🎴
Class
Attributes
suit – integer (0‑3) representing Clubs, Diamonds, Hearts, Spades.
rank – integer (1‑13) where 1 = Ace, 11 = Jack, 12 = Queen, 13 = King.
Class attribute suitList – shared list of suit names
(["Clubs","Diamonds","Hearts","Spades"]).
Class attribute rankList – includes a placeholder "narf" at index 0 so that ranks
map directly (1 → 1, 2 → 2, …).
Behavior
__str__ (or print) uses [Link] to index suitList and [Link] to index rankList.
Modifying a class attribute (e.g., [Link][1] = "Swirly Whales") changes the
value for all Card instances.
Definition: Class attribute – a variable defined inside a class definition but outside any method; it
is shared by every instance of the class.
Comparison (__cmp__)
Return value Meaning
1 self is greater than other
-1 self is less than other
0 objects are equal
Exercise: modify __cmp__ so Aces rank higher than Kings (e.g., treat rank 1 as 14).
📦 Deck Class
Structure – [Link] is a list that stores 52 Card objects.
Initialization
class Deck:
def __init__(self):
[Link] = []
for suit in range(4):
for rank in range(1, 14):
[Link](Card(suit, rank))
Printing
printDeck traverses [Link] and prints each card.
__str__ builds a cascade string where each card is indented one more space than
the previous.
def __str__(self):
s = ""
for i in range(len([Link])):
s += " " * i + str([Link][i]) + "\n"
return s
import random
def shuffle(self):
n = len([Link])
for i in range(n):
j = [Link](i, n) # i ≤ j < n
[Link][i], [Link][j] = [Link][j], [Link][i]
Definition: Shuffle – random permutation of a collection such that each possible ordering is equally
likely.
Removing / Dealing
removeCard(card) – returns True if card was present, False otherwise.
popCard() – removes and returns the last element ([Link]()).
isEmpty() – len([Link]) == 0.
class Hand(Deck):
def __init__(self, name=""):
[Link] = [] # override Deck's cards list
[Link] = name
Additional method
def __str__(self):
header = f"Hand {[Link]}"
if [Link]():
return header + " is empty\n"
else:
return header + " contains\n" + Deck.__str__(self)
Definition: Inheritance – a class (child) acquires attributes and methods from another class
(parent), allowing code reuse and extension.
def removeMatches(self):
count = 0
original = [Link][:]
for card in original:
match = Card(3 - [Link], [Link]) # opposite color
if match in [Link]:
[Link](card)
[Link](match)
print(f"Hand {[Link]}: {card} matches {match}")
count += 1
return count
Uses a copy of the list to avoid modifying the list while iterating.
🔗 Linked Lists
Node class
class Node:
def __init__(self, cargo=None, next=None):
[Link] = cargo
[Link] = next
def __str__(self):
return str([Link])
Traversal Example
def printList(node):
while node:
print(node)
node = [Link]
def printBackward(lst):
if lst is None: return
head = lst
tail = [Link]
printBackward(tail)
print([Link], end=' ')
Definition: Recursive data structure – a structure defined in terms of itself (e.g., a list is either
empty or a node pointing to another list).
LinkedList wrapper
Attributes: head (first node) and length.
Provides methods such as addFirst(cargo) and printBackward() (wrapper) that delegate to
[Link]() (helper).
class LinkedList:
def __init__(self):
[Link] = None
[Link] = 0
def addFirst(self, cargo):
node = Node(cargo)
[Link] = [Link]
[Link] = node
[Link] += 1
def printBackward(self):
print("[", end=' ')
if [Link]:
[Link]()
print("]")
Invariant: [Link] must always equal the actual number of nodes reachable from
[Link].
class Stack:
def __init__(self):
[Link] = []
def push(self, item):
[Link](item)
def pop(self):
return [Link]()
def isEmpty(self):
return [Link] == []
Definition: Postfix (Reverse Polish) notation – operators appear after their operands, enabling
stack‑based evaluation without parentheses.
class Queue:
def __init__(self):
[Link] = 0
[Link] = None
def isEmpty(self):
return [Link] == 0
def insert(self, cargo):
node = Node(cargo)
if [Link] is None:
[Link] = node
else:
last = [Link]
while [Link]:
last = [Link]
[Link] = node
[Link] += 1
def remove(self):
cargo = [Link]
[Link] = [Link]
[Link] -= 1
return cargo
class ImprovedQueue:
def __init__(self):
[Link] = 0
[Link] = None
[Link] = None
def isEmpty(self):
return [Link] == 0
def insert(self, cargo):
node = Node(cargo)
if [Link] == 0:
[Link] = [Link] = node
else:
[Link] = node
[Link] = node
[Link] += 1
def remove(self):
cargo = [Link]
[Link] = [Link]
[Link] -= 1
if [Link] == 0:
[Link] = None
return cargo
class PriorityQueue:
def __init__(self):
[Link] = []
def isEmpty(self):
return [Link] == []
def insert(self, item):
[Link](item)
def remove(self):
# find index of maximal item
maxi = 0
for i in range(1, len([Link])):
if [Link][i] > [Link][maxi]:
maxi = i
item = [Link][maxi]
del [Link][maxi] # remove it
return item
class Golfer:
def __init__(self, name, score):
[Link] = name
[Link] = score
def __str__(self):
return "%-16s: %d" % ([Link], [Link])
def __cmp__(self, other):
if [Link] < [Link]: # lower score = higher priority
return 1
if [Link] > [Link]:
return -1
return 0
Inserting Golfer objects into PriorityQueue yields removal in ascending score order (best
golfer first).
🌳 Binary Trees
Node definition
class Tree:
def __init__(self, cargo, left=None, right=None):
[Link] = cargo
[Link] = left
[Link] = right
def __str__(self):
return str([Link])
Recursive traversal examples
Traversal Order (Root‑Left‑Right) Sample code
Preorder Root, then left subtree, then print([Link]);
right subtree printTree([Link]);
printTree([Link])
Inorder Left, Root, Right printTreeInorder([Link]);
print([Link]);
printTreeInorder([Link])
Postorder Left, Right, Root printTreePostorder([Link]);
printTreePostorder([Link]);
print([Link])
Expression tree – internal nodes hold operators (+, *), leaves hold operands.
3
*
2
+
1
def getProduct(tokenList):
a = getNumber(tokenList)
if getToken(tokenList, '*'):
b = getProduct(tokenList) # recursive call for long chains
return Tree('*', a, b)
else:
return a
def getSum(tokenList):
a = getProduct(tokenList)
if getToken(tokenList, '+'):
b = getSum(tokenList) # recursive right side
return Tree('+', a, b)
else:
return a
def getNumber(tokenList):
if getToken(tokenList, '('):
x = getSum(tokenList) # parse sub‑expression
if not getToken(tokenList, ')'):
raise ValueError('missing parenthesis')
return x
else:
x = tokenList[0]
if not isinstance(x, int):
return None
tokenList[0:1] = [] # consume token
return Tree(x, None, None)
Guarantees that addition inside parentheses is performed before surrounding
multiplication.
def animal():
root = Tree("bird") # initial knowledge
while True:
if not yes("Are you thinking of an animal? "):
break
tree = root
while [Link]() is not None:
prompt = [Link]() + "? "
tree = [Link]() if yes(prompt) else [Link]()
guess = [Link]()
if yes("Is it a " + guess + "? "):
print("I rule!")
continue
# learn new animal
animal_name = raw_input("What is the animal’s name? ")
question = raw_input("What question would distinguish a %s from a %s? " %
(animal_name, guess))
[Link](question)
if yes("If the animal were %s the answer would be? " % animal_name):
[Link](Tree(guess))
[Link](Tree(animal_name))
else:
[Link](Tree(animal_name))
[Link](Tree(guess))
Helper
def yes(ques):
from string import lower
ans = lower(raw_input(ques))
return [Link]('y')
Note: The program loses its knowledge when it exits; persisting the tree to a file is a common
extension exercise.
🐞 Debugging Errors
Definition: Debugging is the process of locating, diagnosing, and fixing defects in software.
Error Categories
Category Typical Symptoms Common Strategies
Syntax errors SyntaxError: invalid syntax Check colons, indentation,
during compilation matching quotes/brackets,
correct use of == vs =.
Runtime errors Exceptions (e.g., NameError, Use print statements to trace
TypeError, IndexError) while execution; examine traceback;
program runs add assertions.
Semantic errors Program runs but produces Verify algorithm logic; step
wrong results through with a debugger; write
unit tests for components.
Debugging Techniques
1. Print‑statement tracing – add messages before/after loops, function entry, and before
critical operations.
2. Infinite loop detection – print loop‑condition values each iteration.
3. Infinite recursion detection – ensure a base case exists; print parameters on each call to
see progress toward the base case.
4. Flow of execution tracing – print "entering <function>" at the start of each function.
Class Skeleton
class Fraction:
def __init__(self, numerator, denominator=1):
g = gcd(numerator, denominator)
[Link] = numerator // g
[Link] = denominator // g
Operator Overloading
Operator Method Description
* (multiplication) __mul__(self, other) Multiply numerators and
denominators; supports integer
left operand via __rmul__ =
__mul__.
+ (addition) __add__(self, other) Cross‑multiply and add;
supports integer right operand
via __radd__ = __add__.
Comparison __cmp__(self, other) Returns sign of (a*d - b*c)
where self = a/b, other = c/d.
(Future) -, /, ** __sub__, __div__, __pow__ Implement via
negation/inversion or by
converting to common
denominator.
Multiplication Example
__rmul__ = __mul__
Addition Example
__radd__ = __add__
Comparison Example