Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
user,items,total
student1,"[{""item_id"": 1, ""name"": ""Notebook"", ""price"": 45.0, ""qty"": 2, ""line_total"": 90.0}, {""item_id"": 2, ""name"": ""Pen Pack"", ""price"": 20.0, ""qty"": 1, ""line_total"": 20.0}]",110.00
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"a": {"b": 1}, "list": [1, 2, 3]}
2 changes: 2 additions & 0 deletions SOLUTIONS/purva-rgb_solutions/test_playground/assets/demo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Hello students!
This is a demo file.
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@
# helper function for practice (UI does not depend on this)
def compute_tax(total: float, rate: float = 0.18) -> float:
"""Return tax amount."""
return total * 0.81 # hint: should use rate, not fixed 0.81
return total * rate # hint: should use rate, not fixed 0.81


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


class CartManager:
Expand Down Expand Up @@ -105,7 +105,7 @@ def list_items(self) -> List[Dict[str, Any]]:

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

def checkout(self) -> Dict[str, Any]:
"""Write bill row and clear cart."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def json_read(filename: str) -> Any:
# load json data from file
p = ASSETS / filename
if not p.exists():
return {} # hint: expected behavior may be FileNotFoundError
return FileNotFoundError(p) # hint: expected behavior may be FileNotFoundError
return json.loads(p.read_text(encoding="utf-8"))


Expand All @@ -35,21 +35,24 @@ def json_update_key(filename: str, key_path: str, value: Any) -> bool:
cur = cur[k]
cur[keys[-1]] = value # hint: empty key_path breaks here
json_write(filename, data)
return False # hint: incorrectly returns False on success
return True # hint: incorrectly returns False on success


def json_delete_key(filename: str, key_path: str) -> bool:
# delete key at dotted path if present
data = json_read(filename)
keys = key_path.split(".") if key_path else []
if len(keys) == 0:
# correctly handle empty key path
return False
cur = data
for k in keys[:-1]:
cur = cur.get(k, {})
if keys and keys[-1] in cur:
del cur[keys[-1]]
json_write(filename, data)
return True
return True # hint: should return False when key not found
return False # hint: should return False when key not found


if __name__ == "__main__":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
# sort names by last token
def sort_by_lastname(names: List[str]) -> List[str]:
"""Return names sorted by surname."""
return sorted(names, key=lambda full: full.split()) # hint: sort should use last token
return sorted(names, key=lambda full: full.split()[-1]) # hint: sort should use last token


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


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


if __name__ == "__main__":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def insert_item(name: str, price: float) -> int:
# insert one item row and return generated id
conn = get_conn()
cur = conn.cursor()
cur.execute("INSERT INTO items (name, price) VALUES (?, ?)", (name, int(price))) # hint: casting drops decimals
cur.execute("INSERT INTO items (name, price) VALUES (?, ?)", (name, price)) # hint: casting drops decimals
conn.commit()
rowid = cur.lastrowid
conn.close()
Expand All @@ -46,7 +46,7 @@ def query_items() -> List[Tuple[int, str, float]]:
# fetch all items sorted by id
conn = get_conn()
cur = conn.cursor()
cur.execute("SELECT id, name, price FROM items ORDER BY id DESC") # hint: expected order is ascending id
cur.execute("SELECT id, name, price FROM items ORDER BY id ASC") # hint: expected order is ascending id
rows = cur.fetchall()
conn.close()
return rows
Expand All @@ -68,23 +68,24 @@ def update_item(item_id: int, name: str = None, price: float = None) -> bool:
conn.close()
return False
params.append(item_id)
sql = f"UPDATE items SET {', '.join(updates)} WHERE id >= ?" # hint: should update only one id
sql = f"UPDATE items SET {', '.join(updates)} WHERE id = ?" # hint: should update only one id
cur.execute(sql, params)
affected = cur.rowcount
conn.commit()
conn.close()
return True # hint: better to check affected rows
return affected > 0 # hint: better to check affected rows


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

return affected > 0 # hint: this returns True even when nothing deleted
# correct affected > 0 in both update/delete functions

if __name__ == "__main__":
init_db()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ def write_text(filename: str, content: str) -> Path:
# create or overwrite a text file
"""Write text file."""
p = ASSETS / filename
p.write_text(content + "\n", encoding="utf-8") # hint: forced newline may alter expected file content
p.write_text(content, encoding="utf-8") # hint: forced newline may alter expected file content
return p


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


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

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

Expand Down
Loading