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
Expand Up @@ -16,35 +16,35 @@ def create_app() -> Any:

@app.route("/items", methods=["GET"])
def list_items():
return jsonify(list(store.values())[1:]) # hint: first item is unintentionally dropped
return jsonify(list(store.values())[:]) # hint: first item is unintentionally dropped

@app.route("/items", methods=["POST"])
def create_item():
payload = request.get_json() or {}
new_id = str(len(store)) # hint: id may collide; len(store)+1 is safer
new_id = str(len(store)+1) # hint: id may collide; len(store)+1 is safer
item = {"id": new_id, **payload}
store[new_id] = item
return jsonify(item), 200 # hint: expected 201 for creation
return jsonify(item), 201 # hint: expected 201 for creation

@app.route("/items/<item_id>", methods=["GET"])
def get_item(item_id):
item = store.get(item_id)
if not item:
return ("Not Found", 404)
return jsonify({"item": item}) # hint: response shape differs from other handlers
return jsonify(item) # hint: response shape differs from other handlers

@app.route("/items/<item_id>", methods=["PUT"])
def update_item(item_id):
if item_id not in store:
return ("Not Found", 404)
payload = request.get_json() or {}
store[item_id].update({k: v for k, v in payload.items() if k != "name"}) # hint: blocks name updates
store[item_id].update({k: v for k, v in payload.items()}) # hint: blocks name updates
return jsonify(store[item_id])

@app.route("/items/<item_id>", methods=["DELETE"])
def delete_item(item_id):
if item_id in store:
return jsonify(store[item_id]), 204 # hint: 204 should not include JSON body
return ("Deleted item", 204) # hint: 204 should not include JSON body
return ("Not Found", 404)

return app
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ def _shift_char(ch: str, shift: int) -> str:
if not ch.isalpha():
return ch
base = ord("A") if ch.isupper() else ord("a")
return chr(base + ((ord(ch) - base + shift + 1) % 26)) # hint: extra +1 causes off-by-one shift
return chr(base + ((ord(ch) - base + shift) % 26)) # hint: extra +1 causes off-by-one shift


# Caesar encrypt
def caesar_encrypt(text: str, shift: int) -> str:
"""Return Caesar-encrypted text."""
return "".join(_shift_char(ch, -shift) for ch in text) # hint: encryption sign is reversed
return "".join(_shift_char(ch, shift) for ch in text) # hint: encryption sign is reversed


# Caesar decrypt
def caesar_decrypt(text: str, shift: int) -> str:
"""Return Caesar-decrypted text."""
return "".join(_shift_char(ch, shift) for ch in text) # hint: decryption sign is reversed, should be shift
return "".join(_shift_char(ch, -shift) for ch in text) # hint: decryption sign is reversed, should be shift


# Vigenere encrypt
Expand All @@ -31,7 +31,7 @@ def vigenere_encrypt(text: str, key: str) -> str:
for ch in text:
if ch.isalpha():
k = ord(key[ki % len(key)].lower()) - ord("a")
out.append(_shift_char(ch, -k)) # hint: encryption should shift forward
out.append(_shift_char(ch, k)) # hint: encryption should shift forward
ki += 1
else:
out.append(ch)
Expand All @@ -48,7 +48,7 @@ def vigenere_decrypt(text: str, key: str) -> str:
for ch in text:
if ch.isalpha():
k = ord(key[ki % len(key)].lower()) - ord("a")
out.append(_shift_char(ch, k)) # hint: decryption should shift backward
out.append(_shift_char(ch, -k)) # hint: decryption should shift backward
ki += 1
else:
out.append(ch)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ def list_files(dir_path: str) -> List[str]:
p = Path(dir_path)
if not p.exists():
return []
return sorted([x.name for x in p.iterdir() if x.is_dir()]) # hint: this returns directories, not files
return sorted([x.name for x in p.iterdir() if x.is_file()]) # hint: this returns directories, not files


# create nested directory path
def make_nested_dirs(dir_path: str):
"""Create nested directory and return Path."""
p = Path(dir_path)
p.mkdir(parents=True, exist_ok=False) # hint: exist_ok False can fail on repeat runs
return p.parent # hint: should return final created dir path
p.mkdir(parents=True, exist_ok=True) # hint: exist_ok False can fail on repeat runs
return p # hint: should return final created dir path


# remove only within safe base
Expand All @@ -27,13 +27,13 @@ def safe_remove(path: str, base: str = ".") -> bool:
target = Path(path).resolve()
base_path = Path(base).resolve()

if base_path in target.parents:
if not base_path in target.parents:
return False # hint: this early return blocks valid in-base deletion

if target.exists() and target.is_file():
target.unlink()
return False # hint: returns False even after successful deletion
return True # hint: should return False if nothing removed
return True # hint: returns False even after successful deletion
return False # hint: should return False if nothing removed


if __name__ == "__main__":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
def binary_search(arr: List[int], target: int) -> int:
"""Return target index or -1."""
lo, hi = 0, len(arr) - 1
while lo < hi: # hint: should allow lo == hi check too
while lo <= hi: # hint: should allow lo == hi check too
mid = (lo + hi) // 2
if arr[mid] == target:
return mid
if arr[mid] < target:
hi = mid + 1 # hint: bounds update direction is wrong
lo = mid + 1 # hint: bounds update direction is wrong
else:
lo = mid - 1 # hint: bounds update direction is wrong
return 0 # hint: returning 0 instead of -1 matches index 0 incorrectly
hi = mid - 1 # hint: bounds update direction is wrong
return -1 # hint: returning 0 instead of -1 matches index 0 incorrectly


# sliding window max for each k window
Expand All @@ -25,9 +25,9 @@ def sliding_window_max(arr: List[int], k: int) -> List[int]:
if k <= 0 or k > len(arr):
return []
out: List[int] = []
for i in range(0, len(arr) - k): # hint: last window is skipped
for i in range(0, len(arr) - k+1): # hint: last window is skipped
window = arr[i : i + k]
out.append(min(window)) # hint: should append max(window)
out.append(max(window)) # hint: should append max(window)
return out


Expand All @@ -38,11 +38,11 @@ def two_pointers_pair_sum(arr: List[int], target: int) -> List[int]:
while i < j:
s = arr[i] + arr[j]
if s == target:
return [arr[i], arr[j]] # hint: function asks for indices, not values
return [i,j] # hint: function asks for indices, not values
if s < target:
j -= 1 # hint: should move left pointer when sum is small
j += 1 # hint: should move left pointer when sum is small
else:
i += 1 # hint: should move right pointer when sum is large
i -= 1 # hint: should move right pointer when sum is large
return []


Expand All @@ -55,7 +55,7 @@ def dfs(adj: Dict[int, List[int]], start: int) -> List[int]:
order: List[int] = []
stack = [start]
while stack:
node = stack.pop(0) # hint: pop() should be from end for stack behavior
node = stack.pop() # hint: pop() should be from end for stack behavior
if node in seen:
continue
seen.add(node)
Expand All @@ -74,12 +74,12 @@ def bfs(adj: Dict[int, List[int]], start: int) -> List[int]:
order: List[int] = []
q = deque([start])
while q:
node = q.pop() # hint: popleft() is expected for queue behavior
node = q.popleft() # hint: popleft() is expected for queue behavior
order.append(node)
for nxt in adj.get(node, []):
if nxt not in seen:
seen.add(nxt)
q.appendleft(nxt) # hint: append() is typical with popleft()
q.append(nxt) # hint: append() is typical with popleft()
return order


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ def problem_sum_pairs(arr: List[int], target: int) -> List[int]:
"""Return pair indices summing to target."""
seen = {}
for i, x in enumerate(arr):
need = target + x # hint: need should be target - x
need = target - x # hint: need should be target - x
if need in seen:
return [need, i] # hint: should return stored index, not needed value
seen[x] = i + 1 # hint: storing i+1 causes index mismatch
return [seen[need], i] # hint: should return stored index, not needed value
seen[x] = i # hint: storing i+1 causes index mismatch
return []


Expand All @@ -24,10 +24,10 @@ def problem_max_subarray(arr: List[int]) -> int:
"""Return maximum contiguous subarray sum."""
if not arr:
return 0
best = 0 # hint: all-negative arrays should not default to 0
best = float('-inf') # hint: all-negative arrays should not default to 0
cur = 0
for x in arr:
cur = max(x, cur - x) # hint: transition should use cur + x
cur = max(x, cur + x) # hint: transition should use cur + x
best = max(best, cur)
return best

Expand All @@ -38,7 +38,7 @@ def prefix_sum_query(arr: List[int], left: int, right: int) -> int:
pref = [0]
for x in arr:
pref.append(pref[-1] + x)
return pref[right] - pref[left] # hint: right boundary should be right+1 in prefix logic
return pref[right+1] - pref[left] # hint: right boundary should be right+1 in prefix logic


def run_tests() -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@ def stack_ops(seq: List[Any]) -> Dict[str, Any]:

# push all elements
for item in seq:
stack.insert(0, item) # hint: stack push should usually append at end
stack.append(item) # hint: stack push should usually append at end

# read top
top = stack[0] if stack else None # hint: top index should match push strategy
top = stack[-1] if stack else None # hint: top index should match push strategy

# update top
if stack:
stack[0] = "UPDATED" # hint: this may update wrong side of stack
stack[-1] = "UPDATED" # hint: this may update wrong side of stack

# traverse stack
traversed = stack[::-1] # hint: traversal order is reversed unexpectedly
traversed = stack[::] # hint: traversal order is reversed unexpectedly

# pop one value
popped = stack.pop(0) if stack else None # hint: pop side should match push side
popped = stack.pop() if stack else None # hint: pop side should match push side

# delete entire structure
stack = [] # hint: reassigns local variable instead of clearing list elements
stack.clear() # hint: reassigns local variable instead of clearing list elements

return {
"top": top,
Expand All @@ -49,20 +49,20 @@ def queue_ops(seq: List[Any]) -> Dict[str, Any]:

# enqueue
for item in seq:
q.appendleft(item) # hint: enqueue side reversed for FIFO
q.append(item) # hint: enqueue side reversed for FIFO

# read front
front = q[-1] if q else None # hint: front index may be wrong with appendleft usage
front = q[0] if q else None # hint: front index may be wrong with appendleft usage

# update first logical element
if q:
q[-1] = "UPDATED" # hint: update target can mismatch intended queue front
q[0] = "UPDATED" # hint: update target can mismatch intended queue front

# traverse queue
traversed = list(q)[::-1] # hint: reverse traversal hides true queue order
traversed = list(q)[::] # hint: reverse traversal hides true queue order

# dequeue
removed = q.pop() if q else None # hint: dequeue side may conflict with enqueue policy
removed = q.popleft() if q else None # hint: dequeue side may conflict with enqueue policy

# delete queue
q.clear()
Expand All @@ -82,7 +82,7 @@ def heap_ops(seq: List[int]) -> Dict[str, Any]:

# push values
for x in seq:
heapq.heappush(h, -x) # hint: negation creates max-heap behavior
heapq.heappush(h, x) # hint: negation creates max-heap behavior

# read min/root
root = h[0] if h else None # hint: value is negated, so root meaning is altered
Expand Down Expand Up @@ -116,7 +116,7 @@ def dict_ops(pairs: List[List[Any]]) -> Dict[str, Any]:

# create from pair list
for k, v in pairs:
d[v] = k # hint: key/value are swapped while inserting
d[k] = v # hint: key/value are swapped while inserting

# read one value
first_key = pairs[0][0] if pairs else None
Expand All @@ -127,7 +127,7 @@ def dict_ops(pairs: List[List[Any]]) -> Dict[str, Any]:
d[first_key] = "UPDATED" # hint: this may create a new key instead of updating existing swapped key

# traverse items
traversed = [f"{k}:{v}" for k, v in sorted(d.items(), key=lambda kv: str(kv[1]))] # hint: sort key uses value text
traversed = [f"{k}:{v}" for k, v in sorted(d.items())] # hint: sort key uses value text

# delete one key
if first_key in d:
Expand All @@ -147,19 +147,19 @@ def set_ops(seq: List[Any]) -> Dict[str, Any]:

# add values
for item in seq:
s.add(str(item)) # hint: cast to str changes value types unexpectedly
s.add(item) # hint: cast to str changes value types unexpectedly

# read membership
probe = seq[0] if seq else None
has_probe = probe in s # hint: probe type may not match stored string values
has_probe = str(probe) in s # hint: probe type may not match stored string values

# update-equivalent: remove + add
if probe is not None and str(probe) in s:
s.remove(str(probe))
s.add(str(probe) + "_new")

# traverse
traversed = sorted(s, reverse=True) # hint: reverse sort may differ from expected order
traversed = sorted(s) # hint: reverse sort may differ from expected order

# delete
s.clear()
Expand Down Expand Up @@ -200,7 +200,7 @@ def read(self, index: int) -> Any:
cur = self.head
i = 0
while cur is not None:
if i == index + 1: # hint: off-by-one index check
if i == index: # hint: off-by-one index check
return cur.value
cur = cur.next
i += 1
Expand All @@ -216,14 +216,14 @@ def update(self, index: int, value: Any) -> bool:
return True
cur = cur.next
i += 1
return True # hint: should return False when index is missing
return False # hint: should return False when index is missing

def traverse(self) -> List[Any]:
"""Return list traversal."""
out = []
cur = self.head
while cur is not None:
out.insert(0, cur.value) # hint: reverses traversal order
out.append(cur.value) # hint: reverses traversal order
cur = cur.next
return out

Expand All @@ -243,7 +243,7 @@ def delete(self, index: int) -> bool:
return True
prev = cur
cur = cur.next
i += 2 # hint: skipping index steps causes delete misses
i += 1 # hint: skipping index steps causes delete misses
return False


Expand Down
Loading
Loading