Viva Questions
INT108
Python 3 is the current standard and is not backward compatible with Python 2. This means code written for Python 2 may not run on a Python 3 interpreter without modification. Significant differences include how print statements work (parentheses are required in Python 3) and how integer division is handled.
Checking 'Add Python to PATH' allows you to run Python from the Command Prompt (cmd) or terminal using the simple python command from any directory. Without this, the operating system will not know where the Python executable is located, and you would have to type the full file path to run scripts.
Dynamic Typing means that you do not need to declare the data type (like int or char) of a variable before using it. Python infers the type based on the value assigned. For example, x = 10 makes x an integer, and x = 'Hello' makes it a string automatically.
- Variable names must start with a letter (a-z, A-Z) or an underscore (
_); they cannot start with a number. - They can contain alphanumeric characters and underscores.
- They are case-sensitive (e.g.,
myVarandMyVarare different). - You cannot use Python keywords (reserved words like
if,class,def) as variable names.
/ operator and the // operator? The / operator performs standard division and always returns a float, even if the result is a whole number (e.g., 10 / 2 returns 5.0). The // operator performs Floor Division, which divides the numbers and rounds the result down to the nearest whole number (e.g., 10 // 3 returns 3).
* operator function when applied to a string? When the * operator is used with a string and an integer, it performs repetition. It repeats the string the specified number of times. For example, 'Spam' * 3 results in the string 'SpamSpamSpam'.
NameError in Python? A NameError occurs when the code tries to use a variable that has not yet been defined (assigned a value). This often happens due to misspellings (e.g., typing mesage instead of message) or trying to print a variable before the line of code where it is assigned.
PEMDAS stands for the order of precedence in mathematical operations:
- Parentheses
() - Exponents
** - Multiplication
*and Division/,//,%(evaluated left-to-right) - Addition
+and Subtraction-(evaluated left-to-right).
Composition is the ability to combine simple expressions and statements into compound ones. It allows you to use the result of one expression directly as part of another, such as nesting functions (e.g., print(type(x))) or performing arithmetic inside a function call (e.g., print(10 * 5)).
A single-line comment starts with the hash character (#). Python ignores everything after the # on that line. While Python doesn't have specific multi-line comment syntax, programmers often use triple quotes (''' or """)—technically multi-line strings/docstrings—or multiple lines starting with # to create multi-line comments.
%)? - Checking Parity: Determining if a number is even (
x % 2 == 0) or odd. - Extracting Digits: Getting the right-most digit of a number (e.g.,
123 % 10returns3). - Cyclic Operations: Wrapping values around, such as in clock arithmetic.
random.random() return compared to random.randint(a, b)? random.random() returns a floating-point number between 0.0 (inclusive) and 1.0 (exclusive). random.randint(a, b) returns a random integer such that (inclusive of both endpoints).
Short-circuit evaluation means Python stops evaluating a boolean expression as soon as the result is determined.
- For
and: If the first operand isFalse, Python stops (result is False). - For
or: If the first operand isTrue, Python stops (result is True).
This saves processing time and can prevent errors in the second part of the expression.
= and ==? = is the assignment operator used to assign a value to a variable (e.g., x = 5). == is the relational (equality) operator used to compare two values, returning True if they are equal and False otherwise.
elif instead of a nested else: if structure? elif (chained conditionals) is used when there are more than two possibilities. It makes the code cleaner and flatter (easier to read) than deeply nested if...else structures. Only the first branch with a True condition executes.
while loop called 'indefinite iteration'? It is called indefinite because the number of times the loop will execute is not necessarily known before the loop starts. It continues to run as long as a specific condition remains True, unlike a for loop which iterates over a fixed sequence.
break and continue. break terminates the loop immediately, jumping to the code following the loop. continue skips the rest of the code in the current iteration and jumps back to the top of the loop to check the condition again.
range(2, 10, 2) generate? It generates the sequence: 2, 4, 6, 8.
It starts at 2, stops before 10 (exclusive), and increments by 2 (step value).
Encapsulation involves wrapping a piece of code (like a loop) into a function. This isolates the logic, allows you to name the process (e.g., draw_square()), and makes the main program cleaner and easier to read.
Generalization is the process of taking encapsulated code and making it versatile by replacing specific literal values (like 100 or 4) with variables (parameters). This allows the same function to solve a wider range of scenarios (e.g., drawing a square of any size, not just size 100).
Fruitful functions return a result that can be assigned to a variable or used in an expression (e.g., len()). Void functions perform an action (like print()) but do not return a meaningful value; technically, they return the special value None.
Type Coercion (Implicit) happens automatically when Python converts data types to prevent data loss (e.g., adding an int to a float results in a float). Type Casting (Explicit) is when the programmer manually converts types using functions like int(), float(), or str().
math.ceil(4.2) return and why? It returns 5. The math.ceil(x) function returns the smallest integer greater than or equal to x. Essentially, it always rounds up.
A local variable is defined inside a function. It exists only while the function is executing and is destroyed when the function exits. It cannot be accessed from outside that specific function.
Parameters are the variables listed inside the parentheses in the function definition (the placeholders). Arguments are the actual values sent to the function when it is called (the data).
Positional arguments must be passed in the correct order defined by the function. Keyword arguments are passed with key=value syntax, meaning the order does not matter (e.g., func(b=5, a=10)).
*args in a function definition? You use *args when you do not know beforehand how many arguments will be passed to the function. It allows the function to receive a tuple of arguments, which can then be iterated over.
- Base Case: A condition where the function returns a value without making a recursive call (stopping condition).
- Recursive Case: The part where the function calls itself with a modified argument that moves closer to the base case.
Recursion is memory-intensive because every recursive call creates a new "stack frame" on the memory stack. If there are too many calls (deep recursion), it can lead to a RecursionError: maximum recursion depth exceeded.
- The program pauses execution at the call point.
- Control transfers to the first line of the called function.
- The function body executes.
- Upon completion (or hitting
return), control returns to the caller, resuming exactly where it left off.
It means that once a string is created, its elements (characters) cannot be changed in place. You cannot do str[0] = 'a'. To change a string, you must create a new string with the desired changes.
s[start:stop], is the stop index inclusive or exclusive? The stop index is exclusive. The slice includes characters from start up to, but not including, stop.
Lists are mutable (can be changed after creation) and use square brackets []. Tuples are immutable (cannot be changed) and use parentheses ().
pop() differ from remove() in lists? pop(index) removes an element by its index and returns the value. remove(value) removes the first occurrence of a specific value and does not return it.
a and b using tuple assignment? You can swap them in one line using: a, b = b, a. This implies simultaneous assignment where the right side is packed into a tuple and unpacked into the variables on the left.
Dictionary keys must be unique and immutable types (like strings, numbers, or tuples). Mutable types like lists cannot be used as keys.
get() method instead of bracket notation dict[key]? Using dict[key] raises a KeyError if the key does not exist. The get(key, default) method prevents this error by returning a specific default value (or None) if the key is missing.
Instead of storing a list of lists with many zeros, a dictionary stores only the non-zero elements. The keys are tuples representing coordinates (row, col), and the values are the data. matrix_dict.get((r,c), 0) allows retrieving values, defaulting to 0 for missing keys.
Aliasing occurs when two variables refer to the exact same object in memory (e.g., b = a). Since lists are mutable, changes made via one variable (alias) will be reflected in the other.
A Shallow Copy (e.g., a[:]) copies the list structure but references the same inner objects if nested. A Deep Copy (copy.deepcopy()) recursively copies the list and all nested objects, ensuring total independence between the original and the copy.
A Class is a blueprint or prototype that defines attributes and methods. An Object is a unique instance of that class containing actual data.
__init__ method? __init__ is the constructor method. It is automatically called when a new instance of a class is created and is used to initialize the object's attributes (state).
self represent in a Python class method? self represents the specific instance of the class currently being manipulated. It allows access to the attributes and methods of that specific object.
Inheritance allows a class (Child/Derived) to acquire the methods and properties of another class (Parent/Base). It promotes code reusability.
Method overriding occurs when a child class provides a specific implementation for a method that is already defined in its parent class. The method name remains the same.
super() function in inheritance? super() returns a temporary object of the superclass (parent), allowing the child class to call methods from the parent. This is often used when overriding a method to extend its functionality rather than replacing it entirely.
A private attribute is denoted by double underscores __ prefix (e.g., self.__balance). Python uses name mangling to make these harder to access from outside the class, enforcing data hiding.
Yes, technically they can. Python changes the name internally (Name Mangling) to _ClassName__variableName. You can access it using this mangled name, though it is not recommended.
Python does not support traditional function overloading (multiple methods with the same name but different parameters). If you define two, the last one overwrites the first. Instead, overloading is simulated using default arguments (None) or variable-length arguments (*args).
Class Attributes are shared by all instances of the class. Instance Attributes (defined in __init__ using self) are unique to each specific object.
'w' (Write) opens a file for writing but truncates (deletes) existing content or creates a new file. 'a' (Append) opens a file for writing but places the pointer at the end, preserving existing content.
with statement when opening files? The with statement automatically handles resource management. It ensures the file is closed automatically after the block is executed, even if an exception/error occurs within the block.
read() and readlines()? read() reads the entire file as a single string. readlines() reads the entire file and returns a list of strings, where each string is a line from the file.
file.write() method? No, write() only accepts strings. You must convert integers or other types to strings (using str() or f-strings) before writing them to a text file.
Pickling is the process of serializing a Python object hierarchy (like a dictionary or list) into a byte stream. This allows complex data structures to be saved to a file using the pickle module.
try...except block? It is used to handle runtime errors (exceptions) without crashing the program. Code that might fail goes in try; if an error occurs, the code in except runs to handle the error gracefully.
else block execute in a try...except...else structure? The else block executes only if no exceptions were raised in the try block. It separates the code that might fail from the code that should run only upon success.
. and ^ represent in Regex? . matches any single character (except newline). ^ asserts the start of a string (matches only at the beginning).
re.match() differ from re.findall()? re.match() checks for a match only at the beginning of the string. re.findall() scans the entire string and returns a list of all non-overlapping matches.
\d and \w match in a Regular Expression? \d matches any digit (0-9). \w matches any alphanumeric character (letters a-z, numbers 0-9, and underscore).