Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 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
8 changes: 4 additions & 4 deletions iban/html/iban.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ <h2 id="before-you-begin">Bevor Sie beginnen</h2>
<p>Führen Sie anschließend</p>
<div class="alert alert-primary"><code class="text-dark font-weight-bold">cd
iban</code></div>
<p>aus, um in dieses Verzeichnis zu wechseln. Der Prompt ihres Terminals sollte
<p>aus, um in dieses Verzeichnis zu wechseln. Der Prompt Ihres Terminals sollte
nun <code class="text-danger border border-dark">iban/$</code> anzeigen.
Jetzt können Sie</p>
<div class="alert alert-primary"><code class="text-dark font-weight-bold">code
Expand All @@ -141,7 +141,7 @@ <h2 id="how-to-test">So testen Sie Ihr Programm</h2>
<pre><code>
print(calcCheckDigitsDE(50010517, 123456789)) # Erwartet: 41
print(calcCheckDigitsDE(50640000, 123456789)) # Erwartet: 45
print(calcCheckDigitsDE(48590377, 987654321)) # Erwartet: 23
print(calcCheckDigitsDE(48590377, 987654321)) # Erwartet: 27
</code></pre>
</li>
</ul>
Expand Down Expand Up @@ -185,7 +185,7 @@ <h2 id="how-to-submit">Abgabe</h2>
</p>

<h2 id="how-to-mark">Markierung der Aufgabe als erledigt</h2>
<p>Nachdem Einreichen der Lösung mit <code class="text-danger">submit50</code>,
<p>Nach dem Einreichen der Lösung mit <code class="text-danger">submit50</code>,
nehmen Sie eine Pseudolösung in Moodle vor, indem Sie auf den Button
<button type="submit" class="btn btn-primary" id="sample_solution" disabled>
Aufgabenlösung hinzufügen</button>
Expand Down Expand Up @@ -216,4 +216,4 @@ <h2 id="how-to-mark">Markierung der Aufgabe als erledigt</h2>
</button>
</p>

<p class="text-muted text-right text-nowrap" style="font-size: 0.6em;">generated 2025-10-31 10:41:19</p>
<p class="text-muted text-right text-nowrap" style="font-size: 0.6em;">generated 2025-12-04 09:18:26</p>
2 changes: 1 addition & 1 deletion iban/html/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ <h2 id="aufgabe">Aufgabe</h2>
<pre><code>
print(calcCheckDigitsDE(50010517, 123456789)) # Erwartet: 41
print(calcCheckDigitsDE(50640000, 123456789)) # Erwartet: 45
print(calcCheckDigitsDE(48590377, 987654321)) # Erwartet: 23
print(calcCheckDigitsDE(48590377, 987654321)) # Erwartet: 27
</code></pre>
</li>
</ul>
Expand Down
10 changes: 10 additions & 0 deletions linkedAfter/.cs50.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
submit50:
files: &submit50_files
- !exclude "*"
- !include "*.py"
- !require linkedAfter.py

check50:
files: *submit50_files
checks: checks/main.py

Empty file added linkedAfter/checks/__init__.py
Empty file.
160 changes: 160 additions & 0 deletions linkedAfter/checks/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import check50
import check50.py

FILE_NAME = "linkedAfter.py"


def to_list(ll):
"""LinkedList -> Python-Liste (mit Zyklus-Schutz)."""
out = []
cur = ll.head
seen = 0
while cur is not None:
out.append(cur.value)
cur = cur.next
seen += 1
if seen > 10_000:
msg = f"Linked list appears to have a cycle (more than {seen} nodes)"
raise check50.Failure(msg)
return out


def build_ll(module, values):
"""Erzeugt eine LinkedList über FromPythonlist (wie in der Aufgabe vorgegeben)."""
ll = module.LinkedList()
ll.FromPythonlist(values)
return ll


def a(self, b):
c = self.head
while c is not None:
if c.value == b:
return c
c = c.next
Comment on lines +29 to +34
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function parameter names 'b' and 'c' are non-descriptive single-letter names. Consider using meaningful names like 'value' for the parameter being searched and 'current' for the traversal variable to improve code readability.

Suggested change
def a(self, b):
c = self.head
while c is not None:
if c.value == b:
return c
c = c.next
def a(self, value):
current = self.head
while current is not None:
if current.value == value:
return current
current = current.next

Copilot uses AI. Check for mistakes.
return None
Comment on lines +29 to +35
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The helper function 'a' has a non-descriptive single-letter name that makes the code difficult to understand. This appears to be implementing searchValue functionality but should have a meaningful name like 'search_value_for_test' or similar to clarify its purpose in the test suite.

Copilot uses AI. Check for mistakes.


@check50.check()
def exists():
"""linkedAfter.py exists"""
check50.exists(FILE_NAME)


@check50.check(exists)
def compiles():
"""linkedAfter.py compiles"""
check50.py.compile(FILE_NAME)


@check50.check(compiles)
def has_classes_and_method():
"""ListNode, LinkedList and insertAfterNode exist"""
module = check50.py.import_(FILE_NAME)

if not hasattr(module, "ListNode"):
msg = f"Class `ListNode` not found in {FILE_NAME}"
raise check50.Failure(msg)

if not hasattr(module, "LinkedList"):
msg = f"Class `LinkedList` not found in {FILE_NAME}"
raise check50.Failure(msg)

if not hasattr(module.LinkedList(), "insertAfterNode"):
msg = "Method `insertAfterNode` not found in Class `LinkedList`"
raise check50.Failure(msg)


@check50.check(has_classes_and_method)
def test_frompythonlist_order_is_head_insertion():
"""FromPythonlist: inserts after head (result is reversed input order)"""
module = check50.py.import_(FILE_NAME)

ll = build_ll(module, [1, 2, 8, 4])
expected = [4, 8, 2, 1] # weil insertAfterHead bei Vorwärtsiteration umdreht
actual = to_list(ll)

if actual != expected:
raise check50.Mismatch(str(expected), str(actual))


@check50.check(has_classes_and_method)
def test_insert_after_middle():
"""insertAfterNode inserts after a middle node (in reversed-built list)"""
module = check50.py.import_(FILE_NAME)

ll = build_ll(module, [1, 2, 8, 4]) # Liste: 4 -> 8 -> 2 -> 1
module.LinkedList.searchValue = a
node = ll.searchValue(8)
if node is None:
msg = "searchValue(8) returned None, but 8 should be in the list"
raise check50.Failure(msg)

ll.insertAfterNode(node, module.ListNode(3))

expected = [4, 8, 3, 2, 1]
actual = to_list(ll)
if actual != expected:
raise check50.Mismatch(str(expected), str(actual))


@check50.check(has_classes_and_method)
def test_insert_after_head():
"""insertAfterNode inserts after head"""
module = check50.py.import_(FILE_NAME)

ll = build_ll(module, [10, 20, 30]) # Liste: 30 -> 20 -> 10
module.LinkedList.searchValue = a
head = ll.head
if head is None:
msg = "Linked list head is None after FromPythonlist"
raise check50.Failure(msg)

ll.insertAfterNode(head, module.ListNode(25))

expected = [30, 25, 20, 10]
actual = to_list(ll)
if actual != expected:
raise check50.Mismatch(str(expected), str(actual))


@check50.check(has_classes_and_method)
def test_insert_after_tail():
"""insertAfterNode inserts after last node (tail)"""
module = check50.py.import_(FILE_NAME)

ll = build_ll(module, [10, 20, 30]) # Liste: 30 -> 20 -> 10
module.LinkedList.searchValue = a
tail = ll.searchValue(10) # 10 ist Tail
if tail is None:
msg = "searchValue(10) returned None, but 10 should be in the list"
raise check50.Failure(msg)

ll.insertAfterNode(tail, module.ListNode(5))

expected = [30, 20, 10, 5]
actual = to_list(ll)
if actual != expected:
raise check50.Mismatch(str(expected), str(actual))


@check50.check(has_classes_and_method)
def test_insert_after_none_prevnode():
"""insertAfterNode with prevNode=None:
We expect an exception (ValueError) rather than silently doing nothing."""
module = check50.py.import_(FILE_NAME)

ll = build_ll(module, [1, 2, 3])
module.LinkedList.searchValue = a
prev = ll.searchValue(999) # not in list -> None
new_node = module.ListNode(4)

threw = False
try:
ll.insertAfterNode(prev, new_node)
except ValueError:
threw = True

if not threw:
msg = "insertAfterNode should raise an ValueError when prevNode is None"
Comment thread
MMachmerth marked this conversation as resolved.
Outdated
raise check50.Failure(msg)
Loading