Midterm Study Guide — Weeks 1–5

ENGR 103: Engineering Computation & Algorithmic Thinking  |  Dr. Cheng Li  |  Oregon State University

Jump to Section

How to Study Cheat Sheet Tips Week 1 — Types & Variables Week 2 — Strings, I/O, Branching Week 3 — Loops & Flow Week 4 — Iteration & Guess-and-Check Week 5 — Approximation & Floats Practice Problems Common Exam Errors

📋 How to Prepare for a Programming Exam

A programming midterm tests whether you can read, trace, and write code by hand — without an IDE to autocomplete or highlight errors for you. Here's how to build those skills before exam day.

  1. Write code on paper. The exam is handwritten. Practice writing 10–20 lines on blank paper. You will catch missing colons and wrong indentation much faster when there's no Spyder underlining errors in red.
  2. Trace loops by hand. Pick any for or while loop and write a table of variable values at every iteration. If you can't trace it, you don't understand it.
  3. Retype past studio and homework problems from scratch. Don't look at your solution. This forces recall. Checking it afterwards is a bonus.
  4. Break things on purpose. Take a working loop, delete a colon or change += to +, then explain why it breaks. Debug drills build the same skill tested on "find the error" questions.
  5. Explain your code out loud. If you can describe each line to someone else, you understand it. If you hesitate, that's what to review.
Exam format reminder: Expect a mix of (1) read-and-trace questions, (2) find-the-bug questions, (3) fill-in-the-blank, and (4) write a short block of code from scratch. Tracing and debugging usually account for more points than writing from scratch.

📝 One-Page Cheat Sheet Strategy

You are allowed one 8.5×11 handwritten notes page (double-sided). Use it strategically — don't copy slides verbatim.

Suggested cheat-sheet sections: (1) Data types & operators, (2) if/elif/else skeleton, (3) for loop skeleton, (4) while loop skeleton, (5) approximation loop skeleton, (6) common string methods, (7) float precision gotcha.

Week 1 — Types, Variables, and Bindings Ch 1, 2.1–2.2

Core Data Types

TypeExampleNotes
intx = 7Whole numbers, positive or negative
floatx = 3.14Decimal numbers; stored in binary (not exact)
strx = 'hello'Sequence of characters; immutable
boolx = TrueOnly True or False (capital T/F)

Key Operations

OperatorMeaningExample → Result
+Addition / string concat3 + 47  |  'a' + 'b''ab'
**Exponentiation2 ** 8256
/Float division (always float)7 / 23.5
//Integer (floor) division7 // 23
%Modulo (remainder)7 % 21

Type Conversion

int(3.9)     # → 3    (truncates, does NOT round)
int('42')    # → 42
float(5)     # → 5.0
str(3.14)    # → '3.14'
type(3.14)   # → <class 'float'>
Exam trap: int(3.9) gives 3, not 4. Python truncates toward zero, it does not round.

Variable Binding

A variable is a name bound to an object. Reassigning creates a new binding — it does not change the original object.

x = 5      # x is bound to the integer 5
x = x + 1  # x is now bound to 6; the 5 object is unchanged
y = x      # y and x both point to 6
x = 0      # x now points to 0; y is still 6

Week 2 — Strings, I/O, F-strings, Branching Ch 2.3–2.4

String Indexing and Slicing

s = 'Python'
s[0]     # 'P'   (first character, index 0)
s[-1]    # 'n'   (last character)
s[1:4]   # 'yth' (index 1 up to but NOT including 4)
s[:3]    # 'Pyt' (from start up to index 3)
s[3:]    # 'hon' (from index 3 to end)
len(s)   # 6

Useful String Methods

MethodExample → Result
s.upper()'hello'.upper()'HELLO'
s.lower()'HI'.lower()'hi'
s.strip()' hi '.strip()'hi'
s.replace(a,b)'cat'.replace('c','b')'bat'

Input and Output

name = input('Enter your name: ')   # always returns a string
age  = int(input('Enter your age: '))  # convert if you need a number
print('Hello,', name)               # comma adds a space
print(f'You are {age} years old.')  # f-string

F-String Formatting

x = 3.14159
print(f'{x:.2f}')    # → 3.14  (2 decimal places)
print(f'{x:.4f}')    # → 3.1416
print(f'{x:8.3f}')   # →    3.142  (8 wide, 3 dp, right-aligned)
print(f'{x:.2e}')    # → 3.14e+00  (scientific notation)

n = 42
print(f'{n:05d}')    # → 00042  (zero-padded, width 5)

Branching — if / elif / else

score = 85

if score >= 90:
    print('A')
elif score >= 80:
    print('B')
elif score >= 70:
    print('C')
else:
    print('Below C')

# Compound conditions
if score >= 70 and score < 90:
    print('Passing but not excellent')
Remember: elif and else are only reached if all earlier conditions were False. Order matters — Python evaluates top to bottom and stops at the first True.

Week 3 — Program Flow: Control Flow and Loops Ch 2.5–2.8

for Loop with range()

for i in range(5):           # 0, 1, 2, 3, 4
    print(i)

for i in range(2, 10, 3):   # 2, 5, 8  (start, stop, step)
    print(i)

for i in range(10, 0, -2):  # 10, 8, 6, 4, 2  (counting down)
    print(i)
Key rule: range(start, stop, step) includes start but never includes stop.

while Loop

# Generic pattern
variable = initial_value
while condition_using_variable:
    # do something
    variable = updated_value   # MUST change variable or loop runs forever

# Example: sum 1 + 2 + 3 + ... until sum exceeds 20
total = 0
n = 1
while total <= 20:
    total += n
    n += 1
print(total, n)

break and continue

# break: exit the loop immediately
for i in range(10):
    if i == 5:
        break      # stops at 5; never prints 5, 6, 7, 8, 9
    print(i)

# continue: skip the rest of this iteration
for i in range(8):
    if i % 2 == 0:
        continue   # skip even numbers
    print(i)       # prints 1, 3, 5, 7

Tracing a Loop (Exam Skill)

For the loop below, trace every iteration:

x = 1
count = 0
while x < 50:
    x = x * 3
    count += 1
Trace table:
After iter 1: x=3, count=1  |  After iter 2: x=9, count=2  |  After iter 3: x=27, count=3  |  After iter 4: x=81, count=4  →  loop stops (81 ≥ 50). Final: x = 81, count = 4.

Week 4 — Iteration: Guess-and-Check, Binary, Fractions Ch 3.1, 3.3

Exhaustive Enumeration (Guess-and-Check)

Try every integer candidate until you find the answer or prove it doesn't exist.

# Find the integer cube root of a perfect cube
target = 27
guess = 0
while guess ** 3 < target:
    guess += 1

if guess ** 3 == target:
    print(f'Cube root of {target} is {guess}')
else:
    print(f'{target} is not a perfect cube')
Pattern: Guess-and-check loops increment an integer candidate until candidate**n >= target, then check for exact match. This only finds perfect integer roots — for non-perfect values, use approximation (Week 5).

Binary Representation (Conceptual)

Every integer can be expressed as a sum of powers of 2. Python converts automatically; understanding the concept matters for interpreting float precision limits.

DecimalBinaryPowers of 2
51012² + 2⁰ = 4 + 1
1311012³ + 2² + 2⁰ = 8 + 4 + 1
16100002⁴

Common Iteration Patterns to Know

# Accumulate a running sum
total = 0
for i in range(1, 11):    # 1 through 10
    total += i
print(total)              # 55

# Count how many values satisfy a condition
count = 0
for i in range(1, 101):
    if i % 7 == 0:        # divisible by 7
        count += 1
print(count)              # 14

Week 5 — Approximation Methods and Floating-Point Ch 3.2–3.3

Exhaustive Approximation (Step-and-Check)

Instead of checking every integer, step through small increments until |guess² − target| < epsilon.

# Approximate square root of 2 to within epsilon = 0.001
target  = 2.0
epsilon = 0.001
increment = 0.0001
guess = 0.0

while abs(guess ** 2 - target) >= epsilon:
    guess += increment

print(f'Approximate √2 = {guess:.4f}')
print(f'Error: {abs(guess**2 - target):.6f}')
Golden rule: increment must be much smaller than epsilon. If increment >= epsilon, the loop might step over the answer and never satisfy the condition — causing an infinite loop or a wrong answer.

The Float Precision Problem

0.1 + 0.2 == 0.3    # → False !
0.1 + 0.2           # → 0.30000000000000004

# Correct comparison: use a tolerance
abs((0.1 + 0.2) - 0.3) < 1e-10    # → True

Floats are stored in binary with ~15 significant digits of precision. Some decimal fractions (like 0.1) cannot be represented exactly in binary, so tiny rounding errors accumulate. Never use == to compare two floats — always check abs(a - b) < epsilon.

Approximation Loop Skeleton

# Template: find x where f(x) ≈ target
target    = ___          # what you're looking for
epsilon   = ___          # how close is "close enough"
increment = ___          # step size (must be << epsilon)
guess     = start_value  # starting point

while abs(f(guess) - target) >= epsilon and guess <= upper_limit:
    guess += increment

if abs(f(guess) - target) < epsilon:
    print(f'Found: {guess:.4f}')
else:
    print('No solution found in range')

Useful Built-in Functions for Week 5

FunctionExample → Result
abs(x)abs(-3.7)3.7
round(x, n)round(3.14159, 2)3.14
max(a, b)max(3, 7)7
min(a, b)min(3, 7)3
x ** 0.5Square root (same as √x)

✏️ Practice Problems (Try on Paper First)

Problem 1 — Type & Expression Trace Week 1

What is the value and type of each expression?

7 / 2        # → ?  (type: ?)
7 // 2       # → ?  (type: ?)
7 % 2        # → ?  (type: ?)
int(7 / 2)   # → ?  (type: ?)
str(7 // 2)  # → ?  (type: ?)
Answers: 3.5 (float)  |  3 (int)  |  1 (int)  |  3 (int)  |  '3' (str)

Problem 2 — String Slicing Week 2

Given s = 'Engineering', what does each expression return?

s[0]      # →
s[-3]     # →
s[3:7]    # →
s[:4]     # →
len(s)    # →
Answers: 'E'  |  'i' (index 8)  |  'inee'  |  'Engi'  |  11

Problem 3 — Loop Trace Week 3–4

Trace this code. What does it print?

result = 0
for i in range(1, 6):
    if i % 2 != 0:
        result += i * i
print(result)
Answer: Adds squares of odd numbers in 1–5: 1² + 3² + 5² = 1 + 9 + 25 = 35

Problem 4 — while Loop with break Week 3

What does this code print? Trace each iteration.

n = 100
steps = 0
while n > 1:
    if n % 2 == 0:
        n = n // 2
    else:
        n = 3 * n + 1
    steps += 1
    if steps >= 5:
        break
print(f'n={n}, steps={steps}')
Trace: n=100 → 50 → 25 → 76 → 38 → 19  (step 5 hits break)
Output: n=19, steps=5

Problem 5 — Write an Approximation Loop Week 5

Write a while loop that approximates √7 to within epsilon = 0.0001 using steps of 0.00001, starting from guess = 0.0. Print the result with 4 decimal places.

Model answer:
target    = 7.0
epsilon   = 0.0001
increment = 0.00001
guess     = 0.0

while abs(guess ** 2 - target) >= epsilon:
    guess += increment

print(f'Approximate √7 = {guess:.4f}')
# Expected output: Approximate √7 = 2.6458

Problem 6 — Find the Bug All Weeks

Each snippet has exactly one bug. Identify and fix it.

# Bug A
total = 0
for i in range(1, 11)
    total = total + i
print(total)

# Bug B
x = 5.0
if x > 3 and x < 10
    print('in range')

# Bug C
count = 10
while count > 0:
    print(count)
    count - 1        # intended to count down
Bug A: Missing colon → for i in range(1, 11):
Bug B: Missing colon → if x > 3 and x < 10:
Bug C: count - 1 doesn't update the variable → change to count -= 1

⚠️ Common Exam Errors — Don't Lose Points on These

MistakeWrongCorrect
Missing colonif x > 0if x > 0:
Not updating variablecount + 1count += 1
Off-by-one in rangerange(1, 5) for 1–5range(1, 6)
Comparing floats with ==x**2 == 2.0abs(x**2 - 2.0) < eps
int() rounds instead of truncatesExpecting int(3.9) = 4int(3.9) = 3
String + number without conversion'Score: ' + 95'Score: ' + str(95) or f-string
input() returns str, not intn = input('...') then n + 1n = int(input('...'))
Increment too large in approximationepsilon=0.001, increment=0.01increment must be ≪ epsilon
Wrong indentation levelCode inside loop that should be outsideCheck every block carefully
Using = instead of ==if x = 5:if x == 5: