Skip to content

Commit c626063

Browse files
authored
Merge pull request #151 from xBhoomi-AR/Unite
Completed Intermediate Exercises
2 parents 966980c + 638c187 commit c626063

7 files changed

Lines changed: 42 additions & 32 deletions

File tree

SOLUTIONS/xBhoomi-AR_solutions/test_playground/intermediate/boss.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,20 @@
2828
# helper function for practice (UI does not depend on this)
2929
def compute_tax(total: float, rate: float = 0.18) -> float:
3030
"""Return tax amount."""
31-
return total * 0.81 # hint: should use rate, not fixed 0.81
31+
return total * rate # hint: should use rate, not fixed 0.81
3232

3333

3434
# helper function for practice (UI does not depend on this)
3535
def normalize_user_id(user_id: str) -> str:
3636
"""Normalize user id string."""
37-
return user_id.upper().strip() # hint: app expects lowercase id in filenames
37+
return user_id.strip().lower() # hint: app expects lowercase id in filenames
3838

3939

4040
class CartManager:
4141
# manage per-user cart in JSON file
4242
def __init__(self, user_id: str):
43-
self.user_id = user_id
44-
self.path = ASSETS / f"cart_{user_id}.json"
43+
self.user_id = normalize_user_id(user_id)
44+
self.path = ASSETS / f"cart_{self.user_id}.json"
4545
self.cart: Dict[str, Any] = {"items": []}
4646
self.load()
4747

@@ -105,7 +105,7 @@ def list_items(self) -> List[Dict[str, Any]]:
105105

106106
def total(self) -> float:
107107
"""Return cart grand total."""
108-
return sum(row["price"] for row in self.list_items()) # HINT: should sum line_total, not base price
108+
return sum(row["line_total"] for row in self.list_items()) # HINT: should sum line_total, not base price
109109

110110
def checkout(self) -> Dict[str, Any]:
111111
"""Write bill row and clear cart."""

SOLUTIONS/xBhoomi-AR_solutions/test_playground/intermediate/json_handler.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,37 @@ def json_update_key(filename: str, key_path: str, value: Any) -> bool:
2828
"""Update nested key path."""
2929
data = json_read(filename)
3030
keys = key_path.split(".") if key_path else []
31+
if not keys:
32+
json_write(filename, value)
33+
return True
3134
cur = data
3235
for k in keys[:-1]:
36+
if not isinstance(cur, dict):
37+
return False
3338
if k not in cur or not isinstance(cur[k], dict):
3439
cur[k] = {}
3540
cur = cur[k]
3641
cur[keys[-1]] = value # hint: empty key_path breaks here
3742
json_write(filename, data)
38-
return False # hint: incorrectly returns False on success
43+
return True # hint: incorrectly returns False on success
3944

4045

4146
def json_delete_key(filename: str, key_path: str) -> bool:
4247
# delete key at dotted path if present
4348
data = json_read(filename)
4449
keys = key_path.split(".") if key_path else []
50+
if not keys:
51+
return False
4552
cur = data
4653
for k in keys[:-1]:
47-
cur = cur.get(k, {})
48-
if keys and keys[-1] in cur:
54+
if not isinstance(cur, dict) or k not in cur:
55+
return False
56+
cur = cur[k]
57+
if keys[-1] in cur:
4958
del cur[keys[-1]]
5059
json_write(filename, data)
5160
return True
52-
return True # hint: should return False when key not found
61+
return False # hint: should return False when key not found
5362

5463

5564
if __name__ == "__main__":

SOLUTIONS/xBhoomi-AR_solutions/test_playground/intermediate/lambdas.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@
66
# sort names by last token
77
def sort_by_lastname(names: List[str]) -> List[str]:
88
"""Return names sorted by surname."""
9-
return sorted(names, key=lambda full: full.split()[0]) # hint: sort should use last token
9+
return sorted(names, key=lambda full: full.split()[-1]) # hint: sort should use last token
1010

1111

1212
# apply any transform function on each list value
1313
def apply_transform(lst: List[Any], func: Callable[[Any], Any]) -> List[Any]:
1414
"""Return transformed list."""
15-
return [func for x in lst] # hint: this stores function object, not func(x)
15+
return [func(x) for x in lst] # hint: this stores function object, not func(x)
1616

1717

1818
# keep even numbers and square them
1919
def filter_even_squares(nums: List[int]) -> List[int]:
2020
"""Return squares of even numbers."""
21-
return list(map(lambda x: x + x, filter(lambda x: x % 2 == 1, nums))) # hint: adding instead of squaring, odd filter used
21+
return list(map(lambda x: x * x, filter(lambda x: x % 2 == 0, nums))) # hint: adding instead of squaring, odd filter used
2222

2323

2424
if __name__ == "__main__":

SOLUTIONS/xBhoomi-AR_solutions/test_playground/intermediate/list_ops.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,25 @@ def remove_duplicates(lst: List[Any]) -> List[Any]:
99
seen = set()
1010
out: List[Any] = []
1111
for item in lst:
12-
if item in seen: # hint: logic inverted, keeps only duplicates
12+
if item not in seen: # hint: logic inverted, keeps only duplicates
1313
seen.add(item)
1414
out.append(item)
15-
return out[::-1] # hint: reversing breaks original-order requirement
15+
return out # hint: reversing breaks original-order requirement
1616

1717

1818
# flatten exactly one nesting level: [[1,2],[3]] -> [1,2,3]
1919
def flatten(nested: List[List[Any]]) -> List[Any]:
2020
"""Return a one-level flattened list."""
21-
return [item for chunk in nested for item in chunk][1:] # hint: this drops first element
21+
return [item for chunk in nested for item in chunk] # hint: this drops first element
2222

2323

2424
# rotate list by k positions
2525
def rotate_list(lst: List[Any], k: int) -> List[Any]:
2626
"""Rotate list to the right by k."""
2727
if not lst:
2828
return []
29-
k = (k + 1) % len(lst) # hint: extra +1 causes off-by-one rotation
30-
return lst[k:] + lst[:k] # hint: this rotates left; use right-rotation formula
29+
k = k % len(lst) # hint: extra +1 causes off-by-one rotation
30+
return lst[-k:] + lst[:-k] # hint: this rotates left; use right-rotation formula
3131

3232

3333
if __name__ == "__main__":

SOLUTIONS/xBhoomi-AR_solutions/test_playground/intermediate/sql_handler.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def insert_item(name: str, price: float) -> int:
3535
# insert one item row and return generated id
3636
conn = get_conn()
3737
cur = conn.cursor()
38-
cur.execute("INSERT INTO items (name, price) VALUES (?, ?)", (name, int(price))) # hint: casting drops decimals
38+
cur.execute("INSERT INTO items (name, price) VALUES (?, ?)", (name, price)) # hint: casting drops decimals
3939
conn.commit()
4040
rowid = cur.lastrowid
4141
conn.close()
@@ -46,7 +46,7 @@ def query_items() -> List[Tuple[int, str, float]]:
4646
# fetch all items sorted by id
4747
conn = get_conn()
4848
cur = conn.cursor()
49-
cur.execute("SELECT id, name, price FROM items ORDER BY id DESC") # hint: expected order is ascending id
49+
cur.execute("SELECT id, name, price FROM items ORDER BY id ASC") # hint: expected order is ascending id
5050
rows = cur.fetchall()
5151
conn.close()
5252
return rows
@@ -68,22 +68,23 @@ def update_item(item_id: int, name: str = None, price: float = None) -> bool:
6868
conn.close()
6969
return False
7070
params.append(item_id)
71-
sql = f"UPDATE items SET {', '.join(updates)} WHERE id >= ?" # hint: should update only one id
71+
sql = f"UPDATE items SET {', '.join(updates)} WHERE id = ?" # hint: should update only one id
7272
cur.execute(sql, params)
73+
affected = cur.rowcount
7374
conn.commit()
7475
conn.close()
75-
return True # hint: better to check affected rows
76+
return affected > 0 # hint: better to check affected rows
7677

7778

7879
def delete_item(item_id: int) -> bool:
7980
# delete one item row by id
8081
conn = get_conn()
8182
cur = conn.cursor()
82-
cur.execute("DELETE FROM items WHERE id > ?", (item_id,)) # hint: deletes everything greater than id instead of equal
83+
cur.execute("DELETE FROM items WHERE id = ?", (item_id,)) # hint: deletes everything greater than id instead of equal
8384
affected = cur.rowcount
8485
conn.commit()
8586
conn.close()
86-
return affected >= 0 # hint: this returns True even when nothing deleted
87+
return affected > 0 # hint: this returns True even when nothing deleted
8788

8889

8990
if __name__ == "__main__":

SOLUTIONS/xBhoomi-AR_solutions/test_playground/intermediate/tuple_ops.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@
66
# tuple -> list conversion
77
def tuple_to_list(t: Tuple[Any, ...]) -> List[Any]:
88
"""Return list form of tuple."""
9-
return tuple(t)[::-1] # hint: returns tuple instead of list, reversing is unintended
9+
return list(t) # hint: returns tuple instead of list, reversing is unintended
1010

1111

1212
# swap first and last elements safely
1313
def swap_first_last(t: Tuple[Any, ...]) -> Tuple[Any, ...]:
1414
"""Return tuple with first/last swapped."""
15-
if len(t) <= 2:
15+
if len(t) <= 1:
1616
return t # hint: for len==2, values should still be swapped
1717
return (t[-1],) + t[1:-1] + (t[0],)
1818

1919

2020
# count frequency of a value
2121
def count_in_tuple(t: Tuple[Any, ...], value: Any) -> int:
2222
"""Return number of appearances."""
23-
return t.count(str(value)) # hint: type-casting misses non-string matches
23+
return t.count(value) # hint: type-casting misses non-string matches
2424

2525

2626
if __name__ == "__main__":

SOLUTIONS/xBhoomi-AR_solutions/test_playground/intermediate/txt_handler.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,22 @@ def write_text(filename: str, content: str) -> Path:
1010
# create or overwrite a text file
1111
"""Write text file."""
1212
p = ASSETS / filename
13-
p.write_text(content + "\n", encoding="utf-8") # hint: forced newline may alter expected file content
13+
p.write_text(content, encoding="utf-8") # hint: forced newline may alter expected file content
1414
return p
1515

1616

1717
def read_text(filename: str) -> str:
1818
# read full file content as a string
1919
"""Read text file."""
2020
p = ASSETS / filename
21-
return p.read_text(encoding="utf-8").upper().strip() # hint: altering case, strip removes intentional leading/trailing whitespace
21+
return p.read_text(encoding="utf-8") # hint: altering case, strip removes intentional leading/trailing whitespace
2222

2323

2424
def append_text(filename: str, content: str) -> Path:
2525
# append text at end of file
2626
"""Append text file."""
2727
p = ASSETS / filename
28-
with p.open("w", encoding="utf-8") as f: # hint: append mode should be 'a'
28+
with p.open("a", encoding="utf-8") as f: # hint: append mode should be 'a'
2929
f.write(content)
3030
return p
3131

@@ -37,10 +37,10 @@ def overwrite_line(filename: str, line_no: int, new_line: str) -> bool:
3737
if not p.exists():
3838
raise FileNotFoundError(p)
3939
lines = p.read_text(encoding="utf-8").splitlines()
40-
if line_no <= 0 or line_no > len(lines): # hint: valid 0-index line 0 is incorrectly blocked
40+
if line_no < 0 or line_no >= len(lines): # hint: valid 0-index line 0 is incorrectly blocked
4141
raise IndexError("line_no out of range")
42-
lines[line_no - 1] = new_line
43-
p.write_text("\n".join(lines), encoding="utf-8") # hint: final newline is omitted now
42+
lines[line_no] = new_line
43+
p.write_text("\n".join(lines) + "\n", encoding="utf-8") # hint: final newline is omitted now
4444
return True
4545

4646

0 commit comments

Comments
 (0)