Python Basics: Operators, Logic, Loops, Strings, Functions, Lists, Dictionaries and File I/O
Python Basics, Operators, Logic and Loops
Syntax and Reading Code
Variables such as x, y, value, word, text, n, i, total, and result are ordinary variable names, not Python commands. x=5 assigns or reassigns a value, while == compares equality. Python runs statements from top to bottom, expressions follow operator precedence, and chained methods run from left to right: s.lower().title().
#starts a comment that is ignored.- Indentation groups blocks of code.
:begins anif,for,while, ordefblock.()is used for function calls and grouping.[]is used for lists, indexing, and slicing.{}is used for dictionaries, sets, and f-string placeholders..method()calls a method.- Quotes
'...'or"..."create strings.
Python is case-sensitive: True, False, and None are capitalized, and x is not the same as X. An error stops execution unless it is handled.
Types and Casting
- int: integer, such as
5. - float: decimal number, such as
5.0. - str: text, such as
'5'. - bool:
TrueorFalse. - None: absence of a value, with type
NoneType.
type(x) returns the type. int(5.9) gives 5, and int(-5.9) gives -5 because it truncates toward 0. int('7') gives 7, but int('7.0') raises a ValueError. float('7') gives 7.0, and str(5) gives '5'. bool(x) tests truthiness.
input('prompt') always returns a string. Use int(input(...)) to get an integer or float(input(...)) to get a decimal number. '7'+str(3) gives '73', int('7')+3 gives 10, 'ha'*3 gives 'hahaha', and '7'+3 raises a TypeError. Adding an int and a float gives a float, so 3*2.0 gives 6.0. Note that True==1 and False==0, so booleans behave as numbers in calculations.
Truthiness
The following values are falsy: 0, 0.0, False, None, '', [], (), {}, and set(). Non-empty strings such as '0', 'False', and ' ', non-zero numbers including -1, and non-empty containers are truthy.
Printing and Formatting
print(a,b)adds a default space between values.print(a,b,sep='@',end='!')changes the separator and ending.print()prints a newline.\nis a newline,\tis a tab,\\is a backslash, and\'is a quote.repr(s)displays escapes and quotes for inspection.
format(x,'.2f') returns a string with two decimals. The same result can be written as f'{x:.2f}'. Other useful patterns include f'{x:05d}' to zero-pad an integer to width 5 (18 becomes 00018), f'{x:>8}' to right-align, < to left-align, ^ to center, f'{x:.2e}' for scientific notation, and f'{x:,.2f}' for commas and two decimals.
'{} {}'.format(a,b) fills placeholders in order, and '{1} {0}'.format('a','b') gives 'b a'. The older %d, %f, and %s codes are for int, decimal, and string values. format(10/3,'.2f') gives the string '3.33'.
Arithmetic and Precedence
+addition, or string and list concatenation.-subtraction.*multiplication, or repetition./true division, which always returns a float:4/2gives2.0.//floor division, which rounds down toward negative infinity:10//3gives3and-9//4gives-3. If a float is involved, the result is a float:5.0//2gives2.0.%remainder:10%4gives2,15%6gives3, and17%5gives2.**exponent:2**3gives8,2**3**2gives512(right-associative),(2**3)**2gives64, and-2**2gives-4.
Dividing by zero with / or // raises a ZeroDivisionError. For positive b, the remainder satisfies a == (a//b)*b + (a%b), with the remainder ranging from 0 to b-1.
Operator precedence, from highest to lowest, is: parentheses, **, unary + and -, * / // %, + and -, comparisons (<, <=, >, >=, ==, !=, is, in), not, and, and or. Comparisons can be chained: a>b>c means (a>b) and (b>c).
Augmented assignment operators (+=, -=, *=, /=, //=, %=, **=) update the left variable: x+=y means x=x+y. Note that >= and <= are comparisons, not augmented assignments.
Booleans and Short-Circuit Evaluation
not x gives the opposite truthiness. and returns the first falsy operand, or the last operand if none is falsy. or returns the first truthy operand, or the last operand if none is truthy. Examples: 0 and 99 gives 0, 5 and 9 gives 9, 0 or 'yes' gives 'yes', and 5 or 9 gives 5.
Evaluation short-circuits: 0 and (1/0) gives 0 with no error, and 1 or unknown gives 1 with no error, but 0 or unknown raises a NameError. Two equal numeric literals are not guaranteed to share identity, so avoid using is for numeric equality.
Branches
In an if/elif/else chain, only the first matching branch executes. An elif is checked only if the earlier branches are false, and else is the catch-all branch. Separate if statements can each run. Indentation determines which else belongs to which if.
A ternary expression has the form A if condition else B. For example, with x=7, the code if x<5: print('Low') followed by elif x%2==1: print('Odd') and else: print('Other') prints Odd.
Loops
A for loop iterates over characters, lists, tuples, sets, dictionary keys, or range objects. A while loop repeats while its condition is truthy, so update the counter to avoid an infinite loop.
range(stop)produces 0 tostop-1.range(start,stop[,step])includesstartand excludesstop; the default step is +1.range(2,10,3)gives 2, 5, 8;range(10,2,-3)gives 10, 7, 4.range(5,3,+1)is empty (not an error), andrange(5,3,-1)gives 5, 4.step=0raises aValueError.
list(range(...)) displays the numbers, while range(...) alone shows a range object. len(range(...)) gives the number of generated values.
breakexits the nearest loop immediately.continueskips the rest of the current iteration and moves to the next.passdoes nothing; later statements still run.returnexits the function, not merely the loop.
In nested loops, break leaves only the inner loop. Using continue in a while loop before the counter increment causes an infinite loop. A for or while loop’s else block runs only if the loop completes without a break.
Common patterns include accumulators (total=0; total+=n, and product=1; product*=n) and sentinels (if input=='done': break). If total is checked after the addition, the value that crossed the threshold is preserved when breaking.
Round, Abs and ASCII
round(x[,ndigits]) rounds to a number of decimal places; n=-1 rounds to the nearest ten and n=-2 to the nearest hundred. Exact halfway values round to the nearest even number: round(2.5) gives 2, round(3.5) gives 4, and round(450.,-2) gives 400.0. Because of binary floating-point representation, round(2.675,2) gives 2.67.
abs(-5) gives 5, pow(2,3) gives 8, and divmod(10,3) gives (3,1). ord(ch) returns the code of a character, and chr(code) returns the character for a code. The space character ' ' has code 32 (not 0), digits '0' to '9' are 48 to 57, uppercase 'A' to 'Z' are 65 to 90, and lowercase 'a' to 'z' are 97 to 122. For example, chr(65) gives 'A' and ord('a')-ord('A') gives 32.
Strings compare left to right by Unicode code point, so uppercase sorts before lowercase ('A' < 'a' is True), and a shorter matching prefix sorts first ('Hell' < 'Hello'). min('cBaD') gives 'B' and min('PYTHON') gives 'H'.
Strings, Slicing and Classifiers
String Basics and Indexing
Strings are immutable and ordered, so s[0]='X' is not allowed. Spaces and punctuation count as characters. Indexing starts at 0, and negative indexes count from the right, with -1 the last character. For s='network', s[3] is 'w', s[-1] is 'k', and s[7] raises an IndexError.
Slicing
The slice syntax is seq[start:stop:step]. The start is included, the stop is excluded, and the step defaults to 1. A positive step moves right and needs start before stop; a negative step moves left and needs start after stop. A step of 0 raises a ValueError. Omitted start and end values refer to the sequence edges in the step direction.
s[3:3:-1]gives''for'network', ands[5:2:1]gives''for'computer'.'PYTHON'[:3]gives'PYT',[1:4]gives'YTH',[::2]gives'PTO', and[::-1]gives'NOHTYP'.'PYTHON'[-1:1:-2]gives'NH',[0::-1]gives'P',[0:0:-1]gives'',[-2:]gives'ON',[:-2]gives'PYTH', and[::-2]gives'NHY'.'triangle'[6:1:-2]gives'lni'.
A -1 in the start or stop is a position, while a -1 in the step indicates direction. s[::] makes a copy. Out-of-range slices are clipped, while out-of-range single indexes raise an error.
Built-in Functions for Strings
len(s) gives the number of characters, min(s) and max(s) give the lowest and highest code-point characters, sorted(s) returns a sorted list of characters, list(s) returns a list of characters, str(x) gives the string representation, ord(s) needs a single character, and chr(n) converts a code to a character. The in and not in operators check substrings, so 'th' in 'python' is True. Comparisons with <, >, ==, and != are lexicographic and case-sensitive.
Case Methods
Case methods return a new string and leave the original unchanged:
s.upper()converts all characters to uppercase.s.lower()converts all characters to lowercase.s.capitalize()uppercases the first character and lowercases the rest.s.title()capitalizes each word.s.swapcase()swaps upper and lower case.s.casefold()performs aggressive lowercasing for comparisons.
Methods chain from left to right: 'hELLO wORLD'.lower().capitalize() gives 'Hello world', 'hELLO wORLD'.title() gives 'Hello World', and 'HELLO'.lower().upper() gives 'HELLO'. To keep a change, assign it: s=s.upper().
Classifiers
All classifiers return a boolean and are generally False for an empty string:
s.isalpha(): letters only.s.isalnum(): letters and digits, no spaces.s.isdigit(): digit characters.s.isnumeric(): numeric symbols, including fractions.s.isdecimal(): decimal digit characters, the most restrictive test.s.isspace(): whitespace only, with at least one character.s.isupper(): all cased letters are uppercase; digits are allowed, and at least one cased letter is required.s.islower(): all cased letters are lowercase.s.istitle(): words are in title case.
Examples: 'abc123'.isalnum() is True and .isalpha() is False; '123'.isdigit() is True; ' '.isspace() is True, but ''.isspace() is False; 'ABC123'.isupper() is True, but '123'.isupper() is False; 'Hello World'.istitle() is True, but 'hello world'.istitle() is False; '²'.isdigit() is True, '½'.isnumeric() is True, and '½'.isdigit() is False.
Search and Count
s.find(sub[,start[,end]]) returns the index of the first occurrence or -1 if it is missing. s.index(sub[,start[,end]]) returns the same index but raises a ValueError if missing. s.rfind(sub) finds the last occurrence, and s.count(sub[,start[,end]]) counts non-overlapping matches. All use 0-based indexes. 'banana'.find('na') gives 2, 'banana'.find('z') gives -1, 'banana'.count('a') gives 3, 'committee'.count('t') gives 2, and 'programming'.find('mm') gives 6. An index of 0 is a valid result, so do not confuse it with False.
Stripping, Splitting and Joining
s.strip() removes whitespace from both ends, s.lstrip() from the left only, and s.rstrip() from the right only. Internal characters are kept. s.strip(chars) removes any character in the given set from both edges, not a whole substring: 'xyHelloxy'.strip('xy') gives 'Hello', and 'good baby good'.strip('odog') gives ' baby '.
s.split(sep=None,maxsplit=-1) returns a list. With the default separator, whitespace groups are used: 'a b'.split() gives ['a','b']. With an explicit separator, empty pieces are kept: 'a b'.split(' ') gives ['a','','','b'], and 'a,b,,c'.split(',') gives ['a','b','','c']. 'a,b,c,d'.split(',',2) gives ['a','b','c,d']. The separator cannot be an empty string.
' '.join(['a','b']) gives 'a b', and all items must be strings. Note that 'a,b'.split(',') returns a list, not a tuple.
Replace and Start/End Checks
s.replace(old,new[,count]) returns a new string with all occurrences replaced unless a count is given: 'mississippi'.replace('s','z') gives 'mizzizzippi', and 'banana'.replace('a','o',1) gives 'bonana'. The replacement is case-sensitive.
s.startswith(prefix[,start[,end]]) and s.endswith(suffix[,start[,end]]) return booleans: 'Python'.startswith('Py') is True, but 'Python'.startswith('py') is False.
Escapes and Traversal
The escape \n is a newline, \t is a tab, \\ is a literal backslash, and \' is an escaped quote. Triple-quoted strings ('''...''' or """...""") allow multi-line text and docstrings. A \n counts as one character. print(repr(s)) helps reveal hidden whitespace and empty strings.
Iterate over characters with for ch in s:, or use indexes with for i in range(len(s)): and s[i]. To count matching characters, set count=0 and then use for ch in s: if ch.isdigit(): count+=1. A palindrome check is s==s[::-1], which is case-sensitive unless you normalize the string first. Note that min() and max() on a string compare characters, not word lengths.
Remember that s[2] returns one character, s.find('x') searches for the first occurrence, and s.count('x') counts occurrences. Methods such as upper, lower, title, capitalize, replace, and strip do not change s.
Common Output Traps
print(value[3:3:-1])prints a blank line, since the result is the empty string'', notNone.print('python'[0].upper())printsP, notPYTHON.print('Apple aPPle'.lower().count('p'))prints 4.print('python'[::-2])printsnhy.print('database'[:6:2])printsdtb.
Functions, Modules, Lists, Tuples and Sets
Defining and Calling Functions
def name(param1,param2=default): defines a function with an indented body. Defining a function stores its code; the body runs only when the function is called with name(args). A parameter is a named placeholder in the definition, while an argument is the actual value passed in.
return expression sends a value back and exits the function. print(expression) only displays the value and returns None. A fruitful function returns a useful value, while a void-style function only performs actions or prints, which means it implicitly returns None.
def f(x): return x**3followed byprint(f(3))prints27.def g(x): print(x**3)followed byprint(g(3))prints two lines:27, thenNone.
A function with no explicit return, a bare return, or a path with no return gives None. A return statement prevents later statements in the body from running. Errors in uncalled functions or unexecuted branches do not occur, except syntax errors, which are detected when the code is parsed.
Function Arguments
Positional argument order matters, while keyword arguments such as f(b=3,a=2) bind by name. Defaults are used when an argument is omitted. Required ordinary parameters must come before parameters with defaults: def f(n,m=9,s=1): means f(4) sets n=4, m=9, s=1, and f(4,s=2) sets m=9, s=2. A signature such as def f(a=1,b): is invalid syntax. Missing, extra, or repeated arguments raise a TypeError.
Scope
A local variable inside a function shadows a global variable of the same name. The global x statement lets a function rebind the global x, and nonlocal x refers to the enclosing function’s x. Assigning to a local x makes it local throughout the function, so reading it before assignment raises an UnboundLocalError.
Other Function Features
def returns a function object. Writing f refers to the function, while f() executes it. help(f) and f.__doc__ show documentation, and the first statement in a function can be a docstring in triple quotes. Recursion means a function calls itself and needs a base case. A lambda x: x*2 creates a small function; sort(key=lambda item:item[1]) sorts by the second element of each tuple.
Built-in Functions
print,input,type, andisinstance(x,T).id(x)gives an identity number, which is not proof of pooling.int,float,str,bool,list,tuple,set, anddictare constructors.len(x)gives the length,sum(numbers[,start])gives the total, andminandmaxreturn extremes from a sequence or arguments.abs(-3)gives 3,round(x,n)rounds, andpow(a,b)equalsa**b.sorted(iterable,key=...,reverse=False)returns a new list, andreversed(seq)returns a reverse iterator.enumerate(seq)gives index and value pairs, andzip(a,b)gives pairs of items.help(object)shows documentation, anddir(obj)lists available names.
For min and max with equal values, the first matching argument is kept: min(1,True) gives 1, and min(True,1) gives True. On a dictionary, min and max use the keys. sum([1,2]) gives 3, but sum(['a','b']) raises a TypeError.
The math and random Modules
import math provides math.sqrt(16) (4.0), math.exp(2) (e squared), math.log(x) (natural log), math.log10(x) (base-10 log), and math.pow(2,3) (8.0, a float). The ordinary 2**3 gives the integer 8. sqrt(-1) and log(0) raise a ValueError. With from math import sqrt, you can call sqrt(16) directly.
import random provides random.random(), a float from 0 up to but not including 1; random.randint(a,b), an integer that includes both endpoints; random.randrange([start,]stop[,step]), which excludes the stop; random.uniform(a,b), a random float; random.choice(seq), one element from a non-empty sequence; and random.shuffle(list), which shuffles in place and returns None. Results may differ on each run.
Lists
Lists are ordered, indexed, mutable, and allow duplicates. [] and list() create empty lists. list('Hi') gives ['H','i'], while ['Hi'] has one element and list(5) raises a TypeError. Indexing gives one element, and slicing gives a new list. Assigning lst[0]=99 changes the list, lst + other_list concatenates, and lst*3 repeats references, which can cause aliasing problems with nested lists.
The in and not in operators test membership, and len, min, max, sum (for numbers), and sorted all work on lists. After a=[1,2]; b=a, both names refer to the same list. Use b=a.copy() or b=a[:] to make a new outer list (a shallow copy). Copy and deepcopy differ for nested structures.
List Methods
a.append(x)adds one object at the end:[1,2].append([3,4])gives[1,2,[3,4]].a.extend(iterable)adds each item:[1,2].extend([3,4])gives[1,2,3,4], andextend('34')adds'3'and'4'.extend(34)raises aTypeError.a.insert(i,x)inserts before indexi.a.pop([i])removes and returns the item at an index, by default the last one; an invalid index raises anIndexError.a.remove(value)deletes the first matching value and returnsNone; a missing value raises aValueError.a.index(value[,start[,end]])gives the first position, or raises aValueError.a.count(x)counts occurrences.a.sort(key=...,reverse=False)sorts in place and returnsNone;sorted(a)returns a new sorted list.a.reverse()reverses in place and returnsNone;a[::-1]returns a reversed copy.a.copy()makes a shallow copy, anda.clear()empties the list.del a[i],del a[i:j], anddel adelete an item, a range, or the name itself.a[i:j]=[]deletes a range,a[i:j]=[x,y]replaces a slice with two values, anda[i:j]=[[x,y]]replaces it with one nested list.
append, extend, insert, remove, sort, reverse, and clear return None, while pop returns the removed item. Note that print(a.sort()) prints None, not the list.
List Comprehensions and Loops
A list comprehension has the form [expression for x in iterable if condition]. For example, [n*n for n in range(5)] gives [0,1,4,9,16], and [n for n in range(6) if n%2==0] gives [0,2,4]. Use for x in lst: to iterate over values, or for i in range(len(lst)): to iterate over indexes. Avoid changing a list while iterating over it when possible.
Tuples
Tuples are ordered, immutable, and allow duplicates. () is an empty tuple, and (5,) is a one-element tuple, while (5) is just the integer 5. tuple([1,2]) converts a list to a tuple. You can read and slice tuples with t[0], t[-1], t[1:3], and t[::-1], but you cannot assign to items or append. Tuples support count, index, len, and min, max, sum for numeric tuples. Unpacking works as in a,b=(3,4). A tuple that contains a list can have that inner list modified.
Sets
Sets contain unique, unordered, mutable elements and do not support indexing. {1,2} creates a set, and {1,1,2} has two elements. Note that {} creates an empty dictionary, so use set() for an empty set. set('aba') gives the unique characters.
set.add(x)adds one item, andset.update(iterable)adds many.set.remove(x)raises aKeyErrorif the item is missing, whileset.discard(x)does nothing.set.pop()removes an arbitrary element,set.clear()empties the set, andset.copy()makes a copy.x in stests membership.
Set operations include A|B (union), A&B (intersection), A-B (only in A), and A^B (in exactly one of the two). A<=B tests a subset, and A>=B tests a superset; the methods A.issubset(B) and A.issuperset(B) do the same. Set elements must be hashable, so a list cannot be a member. An ordinary set is mutable, while a frozenset is immutable.
Dictionaries, File I/O and Exam Traps
Dictionaries
A dictionary maps keys to values, for example d={'key':value,1:'one'} or dict(Course='ITSS3311'). {} and dict() create an empty dictionary. In modern Python, dictionaries keep insertion order and are mutable. Keys must be unique and hashable (strings, integers, or tuples without mutable parts), while values can be anything. A duplicate key keeps the last value: {1:3,1:5} becomes {1:5}.
d['key']returns the value, but a missing key raises aKeyError.d.get(key[,default])returns the stored value orNone(or the default) and does not insert a missing key.d[key]=valueadds or updates an entry, andd[key]+=1increments a numeric value.'key' in dchecks the keys, not the values; use3 in d.values()to check values.max(d),min(d), andsorted(d)work on the keys. Mixed unorderable key types cause aTypeError.
Other methods include d.keys(), d.values(), and d.items(), which return views (not lists); list(d.keys()) converts a view to a list. d.get(k,0) returns the value or 0. d.pop(k[,default]) removes the key and returns its value, and d.popitem() removes and returns the last inserted pair. d.update(other) adds or overwrites pairs and returns None. d.setdefault(k,default) returns the old value or inserts the default if the key is absent. d.clear() empties the dictionary, d.copy() makes a shallow copy, del d[k] removes an entry, and del d deletes the name. To rename a key, use d['new']=d.pop('old'). len(d) gives the number of pairs.
Loop over a dictionary with for key in d: or for key in d.keys(): for keys, for val in d.values(): for values, and for k,v in d.items(): to unpack pairs. For example, with d={'a':2,'b':3}, list(d.items()) gives [('a',2),('b',3)]. Use sorted(d) to alphabetize the keys.
Dictionary Get Cases
For d={'apple':2}: d.get('pear') gives None, d.get('apple') gives 2, d.get('pear',0) gives 0, and d.get('apple',0) gives 2. None of these change the dictionary. By contrast, d['pear'] raises a KeyError, and d['pear']=0 inserts the key.
Counting Pattern
To count characters with a dictionary, use counts={} and then for ch in 'banana': counts[ch]=counts.get(ch,0)+1, which gives {'b':1,'a':3,'n':2}. The same pattern works for words. To find the most frequent key, use max(counts,key=counts.get) on a non-empty dictionary. To check for presence, use if k in d:, or d.get(k,0) when a safe default is needed.
File I/O
open('file.txt','r') opens a file for reading; a missing file raises a FileNotFoundError. Mode 'w' writes and creates or truncates the file, 'a' appends to the end and creates the file if needed, and 'x' creates a new file and raises an error if it already exists.
f.read()reads all remaining content, andf.read(n)reads up to n characters.f.readline()reads one line, andf.readlines()returns a list of the remaining lines.for line in f:iterates over the lines.f.write('text\n')writes a string with no automatic newline and returns the number of characters written.f.close()closes the file,f.seek(0)returns to the beginning, andf.tell()reports the current position.
Using with open('file.txt','r') as f: closes the file automatically when the block ends. Use print(line,end='') to avoid doubled newlines. Reading starts at the current file pointer, so a repeated read can return an empty string. Mode 'w' erases existing content, while 'a' preserves it.
Common Exam Errors
- SyntaxError: bad syntax, such as a missing colon, an invalid
elif, or a required parameter after a default. - IndentationError: incorrect block spacing.
- NameError: an undefined name.
- UnboundLocalError: a local variable is read before assignment.
- TypeError: a wrong type, such as
'3'+3orlist(5). - ValueError: an invalid value, such as
int('hi'),range(...,step=0),.index('missing'), or removing a missing item from a list. - IndexError: an index out of bounds, such as
s[999]orlist.pop(999). - KeyError: a missing dictionary key.
- ZeroDivisionError:
n/0orn%0. - AttributeError: a missing method.
- FileNotFoundError: reading a file that does not exist.
- RecursionError: recursion that goes too deep.
Slices beyond bounds are clipped or return an empty result rather than raising an IndexError. A slice or range in the wrong direction gives an empty result, while a zero step raises a ValueError. After the first uncaught exception, the rest of the program does not run.
High-Yield Traces
'network'[3:3:-1]gives'';'triangle'[6:1:-2]gives'lni';'python'[::-2]gives'nhy';'database'[:6:2]gives'dtb'.min('PYTHON')gives'H';min('cBaD')gives'B'.'programming'.find('mm')gives 6;'committee'.count('t')gives 2;'mississippi'.replace('s','z')gives'mizzizzippi'.print(10/3)shows 3.333…, whileformat(10/3,'.2f')gives the string'3.33'.round(2.675,2)gives 2.67.- With
def g(x): print(x*x)andprint(g(3)), the output is two lines: 9, then None. - With
def f(x): if x>5: return x-2followed byx+3,print(f(4))prints None, because an expression alone is not a return. - With
a=2; b=a; b*=2,ais still 2 andbis 4.
Nested Conditions and Loops
If x=7 and y=3, then elif x%2==1 and y<x-4 checks 3<3, which is False, so the else branch runs. A chained comparison such as a>b>c+1 means both comparisons must hold. A nested break only exits the inner loop, pass is a no-op, and continue skips the rest of the iteration. In loops where total+=n runs before a break check, the total includes the value that triggered the break.
To trace code, update values line by line, apply precedence, identify the nearest block, record every print and return, and stop at a break, return, or error. For exact questions, decide whether the output is a number, a string, a list, an empty string, no output, None, or an error.
Number Bases and Classic Programs
The literals 0b1010 (binary), 0o12 (octal), and 0xA (hexadecimal) all equal decimal 10. bin(10) gives '0b1010', int('1010',2) gives 10, hex(26) gives '0x1a', and oct(8) gives '0o10'. Repeated n%2 gives the rightmost bit, and n//=2 shifts to the next bit. To convert without bin(), use if n==0: return '0', then result='' and while n>0: result=str(n%2)+result; n//=2, and return result.
A multiplication table uses for i in range(1,r+1): print(n,'x',i,'=',n*i). A leap-year test is year%400==0 or (year%4==0 and year%100!=0). A prime test checks that n>1 and that no divisor i exists in range(2,n). A factorial uses product=1; for i in range(1,n+1): product*=i, and Fibonacci numbers use a,b=b,a+b.
