Recursion, Callbacks and Generators
Closures, Decorators & wxPython
NumPy, PyImage, NLTK, Sklearn
Regular Expressions & Modules
Testing & Debugging
100

What will be the output of this code? 

def func(n):

    if n == 0:

        return 0

    return n + func(n-1)

print(func(3))

 

6 (Explanation: 3+2+1+0 = 6)

100

def outer(x):

    def inner():

        return x * 2

    return inner


f = outer(5)

print(f())

10

100

import numpy as np

arr = np.array([1, 2, 3, 4, 5])

print(arr[1:4])

[2 3 4]

100

What is the difference between re.match() and re.search()?

A: re.match() checks for a match only at the beginning of the string, while re.search() searches the entire string for a match.

100

def add(a,b):

    return a+b


assert add(2,2) == 4

print("OK")

OK

200

What is the base case in recursion and why is it essential?

A base case is the condition that stops the recursion. It is essential to prevent infinite recursion and stack overflow errors.

200

Explain any 2 conditions out of 3 for a function to be considered as closure function

nested function

free variable

outer should return inner function

200

In scikit-learn's KNN algorithm, what does the 'K' represent and what happens if K=1?

'K' represents the number of nearest neighbors to consider. If K=1, the algorithm classifies a point based only on its single closest neighbor, which can lead to overfitting.

200

What will re.match(r'\d+', '123abc') return when you call .group() on it?

A: '123'

200

def divide(a, b):

    return a / b


def test_divide():

    assert divide(10, 2) == 5

    assert divide(9, 3) == 3

    assert divide(1, 0) == 0

2 tests pass, 1 test fails with ZeroDivisionError (Explanation: The third assertion causes division by zero which raises an exception)

300

def outer(x):

    def inner(y):

        if y == 0:

            return x

        return outer(x + y)(y - 1)

    return inner


print(outer(5)(3))

11 (Explanation: 5+3+2+1 = 11, recursive calls with decreasing y)

300

When the user RESIZES the window horizontally:

  1. Which button grows the MOST?

  2. Which button does NOT grow at all?

  3. What role do the flags (wx.EXPAND, wx.ALIGN_CENTER_VERTICAL, wx.ALL) play for each?

import wx


app = wx.App()


frame = wx.Frame(None, title="Sizer Test", size=(400, 200))

panel = wx.Panel(frame)


sizer = wx.BoxSizer(wx.HORIZONTAL)


btn1 = wx.Button(panel, label="Save")

btn2 = wx.ToggleButton(panel, label="Play")

btn3 = wx.BitmapButton(panel, bitmap=wx.Bitmap("play_20x20.png"))


sizer.Add(btn1, 1, wx.ALL | wx.EXPAND, 10)

sizer.Add(btn2, 0, wx.ALIGN_CENTER_VERTICAL, 5)

sizer.Add(btn3, 3, wx.EXPAND | wx.ALL, 0)


panel.SetSizer(sizer)

frame.Show()

app.MainLoop()


btn3

btn2


sizer.Add(btn1, 1, wx.ALL | wx.EXPAND, 10)

wx.EXPAND → expands in both directions

wx.ALL + 10 → 10-pixel padding around it

Takes 1 unit of expandable space


sizer.Add(btn2, 0, wx.ALIGN_CENTER_VERTICAL, 5)

No wx.EXPAND → width remains fixed

wx.ALIGN_CENTER_VERTICAL → button stays vertically centered

proportion = 0 → no stretch at all


sizer.Add(btn3, 3, wx.EXPAND | wx.ALL, 0)

wx.EXPAND → grows fully

proportion = 3 → gets largest share of horizontal space

wx.ALL + 0 → no padding


300

import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])

print(arr.shape)

print(arr.reshape(3, 2))

(2, 3) [[1 2] [3 4] [5 6]]

300

import re

text = "Contact: john@email.com and jane@email.com"

pattern = r'\b[a-z]+@[a-z]+\.com'

matches = re.findall(pattern, text)

print(len(matches))

print(matches[0])

john@email.com

300

def factorial(n):

    """

    Calculate factorial.

    >>> factorial(5)

    120

    >>> factorial(0)

    1

    >>> factorial(3)

    6

    """

    if n == 0:

        return 1

    return n * factorial(n-1)


if __name__ == "__main__":

    import doctest

    result = doctest.testmod()

    print(f"Failed: {result.failed}, Attempted:{result.attempted}")

Failed: 0, Attempted: 3 (Explanation: All three doctests pass)

400

def mystery(lst, callback):

    result = []

    for item in lst:

        result.append(callback(item))

    return result


nums = [1, 2, 3,4,5]

output = mystery(nums, lambda x: x**2 if x % 2 != 0 else x)

print(output)

[1, 2, 9,4,25] (Explanation: Odd numbers are squared, even numbers remain same

400

def dec(fn):

    def wrap():

        return fn()+2

    return wrap


@dec

def num():

    return 7**2


print(num())


51

400

import numpy as np

a = np.array([1, 2, 3])

b = np.array([4, 5, 6])

result1 = a * b

result2 = np.dot(a, b)

print(result1)

print(result2)

print(result1.sum() == result2)

[ 4 10 18] 

32 

True

 (Explanation: Element-wise multiplication vs dot product; sum of element-wise equals dot product)

400

import re

print(re.findall(r'\d+', 'a12b003c9'))

['12', '003', '9']

400

Predict which doctest will fail or pass and why: 

def divide_numbers(a, b):

    """

    Divide two numbers.

    >>> divide_numbers(10, 2)

    5.0

    >>> divide_numbers(7, 2)

    3.5

    >>> divide_numbers(9, 3)

    3

    >>> divide_numbers(0, 5)

    0.0

    """

    return a / b


if __name__ == "__main__":

    import doctest

    doctest.testmod()

The third test divide_numbers(9, 3) expects 3 but gets 3.0. Division in Python 3 always returns a float. Failed: 1, Attempted: 4

500

def generator_chain():

    yield 1

    yield from [2, 3, 4]

    yield 5

    yield from range(6, 8)


result = [x**2 for x in generator_chain() if x % 2 == 0]

print(result)

print(result)

[4, 16, 36]

[]

 (Explanation: Even numbers are 2, 4, 6; their squares are 4, 16, 36)

500

def make():

    val = 10

    def f():

        nonlocal val

        val += 5

        return val

    return f


x = make()

print(x(), x(), x())

15 20 25

500

from sklearn.neighbors import KNeighborsClassifier

import numpy as np


X_train = np.array([[1, 1], [2, 2], [3, 3], [6, 6], [7, 7], [8, 8]])

y_train = np.array([0, 0, 0, 1, 1, 1])

X_test = np.array([[4, 4], [5, 5]])


knn = KNeighborsClassifier(n_neighbors=3)

knn.fit(X_train, y_train)

predictions = knn.predict(X_test)

print(predictions)

print(predictions[0] == predictions[1])

[0 1] 

False 

(Explanation: [4,4] is closer to class 0 points, [5,5] is closer to class 1 points based on 3 nearest neighbors)

500

import re

text = "aa aba aaaa abba"

print(re.findall(r'a.b', text))

s = "cat scatter cater cutoff"

print(re.findall(r'ca[t|r]+', s))

print(re.findall(r'a.b', text))

['aab', 'aba']

['cat', 'catter']

500

import pytest

def process_data(numbers):

    if not numbers:

        return []

    return [x ** 2 for x in numbers if x > 0]

def test_process_data():

    # Test 1

    result1 = process_data([1, 2, 3])

    assert result1 == [1, 4, 9], f"Expected [1, 4, 9], got {result1}"

    

    # Test 2

    result2 = process_data([-1, 0, 2, -3, 4])

    assert len(result2) == 2

    assert result2[0] == 4

    assert result2[1] == 16

    

    # Test 3

    result3 = process_data([])

    assert result3 == []

    

    # Test 4

    result4 = process_data([-5, -10])

    assert result4 == [], f"Expected empty list for all negatives"


# How many total assertions are in this test?

# Will all assertions pass?



Total assertions: 6 All assertions pass: Yes 

Breakdown:

  • Test 1: 1 assertion (passes - [1, 4, 9])
  • Test 2: 3 assertions (all pass - length is 2, elements are 4 and 16)
  • Test 3: 1 assertion (passes - empty list)
  • Test 4: 1 assertion (passes - empty list for negative numbers)

(Explanation: Multiple assertions in one test function still count as one test. All pass because the function correctly filters positive numbers and squares them.)








Claude can make mistakes.
Please double-check responses.