Opsi anotasi
Ada beberapa opsi yang umum untuk semua anotasi; di modul terakhir, Anda belajar tentang opsi success_message
dan failure_message
. Dalam modul ini, kita membahas tiga opsi lagi yang dapat diterapkan pada anotasi dan bagaimana mereka dapat digunakan.
name
Opsi name
ini digunakan untuk mengelompokkan berbagai instans kelas anotasi yang mewakili anotasi yang sama secara bersama-sama. Opsi ini digunakan untuk mencegah pesan ditampilkan beberapa kali ketika tidak perlu. Mari kita pertimbangkan contoh berikut: maximum
fungsi memanggil fungsi Python max
untuk memeriksa apakah siswa mengidentifikasi maksimum dengan benar, tetapi satu pesan keberhasilan dicetak untuk setiap input yang diuji fungsi.
>>> max_ref = []
>>> def maximum(l, track=False):
... m = max(l)
... if track:
... max_ref.append(pybryt.Value(
... m,
... success_message="Found the max!",
... failure_message="Did not find the max",
... ))
... return m
>>> test_lists = [[1, 2, 3], [-1, 0, 1], [10, -4, 2, 0], [1]]
>>> for test_list in test_lists:
... maximum(test_list, track=True)
>>> max_ref = pybryt.ReferenceImplementation("maximum", max_ref)
>>> with pybryt.check(max_ref):
... for test_list in test_lists:
... maximum(test_list)
REFERENCE: maximum
SATISFIED: True
MESSAGES:
- Found the max!
- Found the max!
- Found the max!
- Found the max!
Masalah dengan fungsi ini sederhana: anotasi yang dibuat di setiap pengujian pada dasarnya memeriksa hal yang sama, apakah siswa mengembalikan nilai yang benar. Memiliki pesan yang sama yang dicetak beberapa kali membuatnya tampak seperti anotasi menguji kondisi yang berbeda dan mengacaukan laporan yang dihasilkan oleh PyBryt. Kita dapat menutup semua pesan ini bersama-sama dengan menamai anotasi yang dibuat dalam fungsi maximum
:
>>> max_ref = []
>>> def maximum(l, track=False):
... m = max(l)
... if track:
... max_ref.append(pybryt.Value(
... m,
... name="list-maximum",
... success_message="Found the max!",
... failure_message="Did not find the max",
... ))
... return m
>>> test_lists = [[1, 2, 3], [-1, 0, 1], [10, -4, 2, 0], [1]]
>>> for test_list in test_lists:
... maximum(test_list, track=True)
>>> max_ref = pybryt.ReferenceImplementation("maximum", max_ref)
>>> with pybryt.check(max_ref):
... for test_list in test_lists:
... maximum(test_list)
REFERENCE: maximum
SATISFIED: True
MESSAGES:
- Found the max!
Sekarang, kita dapat melihat bahwa pesan hanya dicetak sekali.
Ketika PyBryt menciutkan anotasi ke dalam satu pesan, itu hanya menampilkan pesan keberhasilan jika semua anotasi dalam grup nama terpenuhi. Jika ada pengujian dalam grup yang gagal, pengujian akan menampilkan pesan kegagalan sebagai gantinya. Mari kita perkenalkan bug untuk maximum
menunjukkan:
>>> def maximum(l):
... if len(l) % 2 == 0:
... m = min(l)
... else:
... m = max(l)
... return m
>>> with pybryt.check(max_ref):
... for test_list in test_lists:
... maximum(test_list)
REFERENCE: maximum
SATISFIED: False
MESSAGES:
- Did not find the max
limit
Opsi limit
memungkinkan Anda mengontrol berapa banyak salinan anotasi bernama yang disertakan dalam implementasi referensi. Opsi ini membantu kasus di mana fungsi yang membangun anotasi digunakan kembali berkali-kali selama penugasan. Kasus di mana beberapa pengujian awal cukup untuk memeriksa validitas implementasi dengan mengurangi ukuran implementasi referensi itu sendiri.
Mari kita ilustrasikan ini menggunakan fungsi kita maximum
. Di sini, kami menggunakan implementasi serupa dengan referensi sebelumnya tetapi diatur limit
ke lima anotasi dan mengujinya pada beberapa daftar input.
>>> max_ref = []
>>> def maximum(l, track=False):
... m = max(l)
... if track:
... max_ref.append(pybryt.Value(
... m,
... name="list-maximum",
... limit=5,
... success_message="Found the max!",
... failure_message="Did not find the max",
... ))
... return m
>>> for _ in range(1000):
... test_list = np.random.normal(size=100)
... maximum(test_list, track=True)
>>> print(f"Annotations created: {len(max_ref)}")
>>> max_ref = pybryt.ReferenceImplementation("maximum", max_ref)
>>> print(f"Annotations in reference: {len(max_ref.annotations)}")
Annotations created: 1000
Annotations in reference: 5
Seperti yang Anda lihat, panjang max_ref.annotations
adalah 5 meskipun 1.000 anotasi disertakan dalam daftar yang diteruskan ke konstruktor.
group
Opsi group
ini mirip dengan opsi name
karena digunakan untuk mengelompokkan anotasi bersama-sama, tetapi anotasi ini tidak selalu mewakili "anotasi yang sama"; sebaliknya, anotasi tersebut dikelompokkan menjadi potongan yang bermakna sehingga bagian referensi tertentu dapat diperiksa satu per satu, bukan sekaligus. Opsi ini dapat berguna dalam membangun tugas dengan beberapa pertanyaan di PyBryt.
Misalnya, pertimbangkan tugas yang meminta siswa untuk menerapkan mean
fungsi dan median
. Anda dapat membaginya menjadi dua pertanyaan seperti berikut:
# Question 1
mean_ref = []
def mean(l, track=False):
size = len(l)
if track:
mean_ref.append(pybryt.Value(
size,
name="len",
group="mean",
success_message="Determined the length of the list",
))
m = sum(l) / size
if track:
mean_ref.append(pybryt.Value(
m,
name="mean",
group="mean",
success_message="Calculated the correct mean of the list",
failure_message="Did not find the correct mean of the list",
))
return m
# Question 2
median_ref = []
def median(l, track=True):
sorted_l = sorted(l)
if track:
median_ref.append(pybryt.Value(
sorted_l,
name="sorted",
group="median",
success_message="Sorted the list",
))
size = len(l)
if track:
mean_ref.append(pybryt.Value(
size,
name="len",
group="median",
success_message="Determined the length of the list",
))
middle = size // 2
is_set_size_even = size % 2 == 0
if is_set_size_even:
m = (sorted_l[middle - 1] + sorted_l[middle]) / 2
else:
m = sorted_l[middle]
if track:
mean_ref.append(pybryt.Value(
m,
name="mean",
group="mean",
success_message="Calculated the correct mean of the list",
failure_message="Did not find the correct mean of the list",
))
return m
test_lists = [[1, 2, 3], [-1, 0, 1], [10, -4, 2, 0], [1]]
for test_list in test_lists:
mean(test_list, track=True)
median(test_list, track=True)
assignment_ref = pybryt.ReferenceImplementation("mean-median", [*mean_ref, *median_ref])
Dengan referensi yang dibangun seperti dalam contoh sebelumnya, kita dapat memberi siswa kesempatan untuk memeriksa pekerjaan mereka pada setiap pertanyaan individu sebelum melanjutkan ke pertanyaan berikutnya dengan memberi tahu PyBryt kelompok anotasi mana yang perlu dipertimbangkan:
>>> with pybryt.check(assignment_ref, group="mean"):
... for test_list in test_lists:
... mean(test_list)
REFERENCE: mean-median
SATISFIED: True
MESSAGES:
- Determined the length of the list
- Calculated the correct mean of the list
>>> with pybryt.check(assignment_ref, group="median"):
... for test_list in test_lists:
... median(test_list)
REFERENCE: mean-median
SATISFIED: True
MESSAGES:
- Determined the length of the list
- Sorted the list
>>> with pybryt.check(assignment_ref):
... for test_list in test_lists:
... mean(test_list)
... median(test_list)
REFERENCE: mean-median
SATISFIED: True
MESSAGES:
- Determined the length of the list
- Calculated the correct mean of the list
- Sorted the list