-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproblems_python-practicals.json
More file actions
592 lines (592 loc) · 72.1 KB
/
Copy pathproblems_python-practicals.json
File metadata and controls
592 lines (592 loc) · 72.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
[
{
"slug": "python-practical-alarm-snooze",
"module": "python-practicals",
"title": "Mini-Project: Alarm Clock Snooze Calculator",
"func_name": "calculate_snooze_time",
"return_type": "str",
"param_types": [
"int",
"int",
"int"
],
"param_names": [
"current_hour",
"current_minute",
"snooze_minutes"
],
"statement": "Time calculations often need to handle **wrap-around** behavior — when adding a duration pushes a value past its maximum and it cycles back to the beginning. This is common in clock, calendar, and scheduling applications.\n\nIn this challenge, your task is to calculate a new alarm time after a snooze delay. Given the current hour (0 to 23), current minute (0 to 59), and a snooze duration in minutes, calculate the new time formatted as \"HH:MM\", correctly wrapping around to the next day if the snooze pushes past midnight.\n\nFor example:\n\n- Snoozing for **15 minutes** starting from **7:50** results in a new alarm time of **\"08:05\"**.\n- Snoozing for **20 minutes** starting from **23:50** wraps past midnight to **\"00:10\"**.\n- Snoozing for **0 minutes** starting from **14:30** leaves the time unchanged at **\"14:30\"**.\n\nYour function should return the new alarm time as a string in \"HH:MM\" format, with each component padded to two digits.\n\nThis exercise reinforces several important programming concepts:\n\n- Converting time to a **single unit** (minutes since midnight) for simpler arithmetic.\n- Using the **modulo operator** to handle wrap-around behavior.\n- Formatting output with **zero-padded** digits.\n- Applying **real-world scheduling** logic in code.\n\nTime arithmetic with wrap-around is widely used in alarm clocks, countdown timers, scheduling systems, and any application that works with cyclical time values.",
"original_statement": "An alarm clock app's snooze button needs to calculate a new alarm time by adding a fixed delay onto the current time — including correctly handling the case where that delay pushes the time past midnight into the next day.\n\nWrite the snooze calculation logic for such an alarm app. Given the current hour (0 to 23), current minute (0 to 59), and a snooze duration in minutes, calculate the new alarm time after snoozing, formatted as \"HH:MM\", correctly wrapping around to the next day if the snooze pushes past midnight.\n\nFor example, snoozing for 15 minutes starting from 7:50 results in a new alarm time of \"08:05\". Snoozing for 20 minutes starting from 23:50 results in a new alarm time of \"00:10\", correctly rolling over into the next day.",
"hints": [
"Converting the current time into a single total number of minutes since midnight makes adding a snooze duration a simple addition, rather than juggling hours and minutes as two separate values.",
"Snoozing late at night can push the time past midnight and into the next day — wrapping the total number of minutes using the number of minutes in a full day correctly handles that day rollover.",
"Once the new total minutes since midnight is known, converting it back into separate hours and minutes, each padded to two digits, produces the final displayed alarm time."
],
"difficulty": 4,
"xp_reward": 190
},
{
"slug": "python-practical-alarm-trigger",
"module": "python-practicals",
"title": "Mini-Project: Alarm Trigger Checker",
"func_name": "is_alarm_triggered",
"return_type": "bool",
"param_types": [
"str",
"list"
],
"param_names": [
"current_time",
"alarm_times"
],
"statement": "**Membership testing** — checking whether a value exists in a collection — is a fundamental operation in programming. When multiple items need to be checked in a single operation, efficient lookup becomes important.\n\nIn this challenge, your task is to implement the trigger-checking logic for a multi-alarm clock app. Given the current time as a string and a list of configured alarm times (both formatted as \"HH:MM\"), determine whether the current time matches any of the configured alarms.\n\nFor example:\n\n- A current time of **\"07:00\"** checked against **[\"06:30\", \"07:00\", \"08:00\"]** returns **True**, since it exactly matches the second alarm.\n- A current time of **\"07:30\"** checked against the same list returns **False**, since no alarm is set for that time.\n- An empty alarm list with any current time returns **False**.\n\nYour function should return `True` if the current time matches any configured alarm, `False` otherwise.\n\nThis exercise reinforces several important programming concepts:\n\n- Using the **`in` operator** for membership testing in lists.\n- Checking **string equality** for exact matches.\n- Handling **empty collections** gracefully.\n- Building real-world **event-triggering** logic.\n\nMembership-based triggering is used in alarm systems, notification services, calendar reminders, and event scheduling applications.",
"original_statement": "An alarm clock app that supports multiple configured alarms needs to check, on every tick of the clock, whether the current time matches any one of them.\n\nWrite the trigger-checking logic for such an app. Given the current time and a list of configured alarm times (both formatted consistently, such as \"HH:MM\"), determine whether the current time exactly matches any of the configured alarms.\n\nFor example, a current time of \"07:00\" checked against configured alarms of \"06:30\", \"07:00\", and \"08:00\" should trigger, since it exactly matches the second alarm in the list.",
"hints": [
"An alarm clock app typically supports several separate alarms set for different times, all of which need to be checked at once against the current time.",
"The alarm should trigger the moment the current time matches any one of the configured alarm times exactly — it does not matter which specific alarm matched, only that at least one of them did.",
"Checking membership in a list of alarm times directly answers exactly this question, without needing to loop through and compare each alarm time individually by hand."
],
"difficulty": 4,
"xp_reward": 190
},
{
"slug": "python-practical-bmi-calculator",
"module": "python-practicals",
"title": "Mini-Project: BMI Health Calculator",
"func_name": "calculate_bmi_category",
"return_type": "str",
"param_types": [
"float",
"float"
],
"param_names": [
"weight_kg",
"height_m"
],
"statement": "**Health and fitness calculations** combine mathematical formulas with categorical classification. Body Mass Index (BMI) is a widely used health metric that relates weight and height to standard weight categories.\n\nIn this challenge, your task is to calculate a person's BMI from their weight in kilograms and height in meters, then classify it into one of four standard categories: \"Underweight\" (below 18.5), \"Normal\" (18.5 up to 25), \"Overweight\" (25 up to 30), or \"Obese\" (30 and above).\n\nFor example:\n\n- A weight of **70 kg** and height of **1.75 m** produces a BMI of about **22.86**, which falls in the **\"Normal\"** category.\n- A weight of **95 kg** and height of **1.75 m** produces a BMI of about **31.02**, which falls in the **\"Obese\"** category.\n- A weight of **50 kg** and height of **1.75 m** produces a BMI of about **16.33**, which falls in the **\"Underweight\"** category.\n\nYour function should return the category name as a string.\n\nThis exercise reinforces several important programming concepts:\n\n- Applying a **mathematical formula** (BMI = weight / height²).\n- Using **conditional chains** to classify continuous values.\n- Understanding **boundary inclusivity** (`< 18.5` vs `>= 30`).\n- Translating **health standards** into code logic.\n\nHealth classification systems are used in fitness apps, medical software, insurance calculations, and wellness tracking platforms.",
"original_statement": "A fitness or health-tracking app commonly reports a user's Body Mass Index (BMI) alongside its standard health category, calculated from the user's weight and height.\n\nWrite the BMI calculation logic for such an app. Given a person's weight in kilograms and height in meters, calculate their BMI and categorize it as \"Underweight\" (below 18.5), \"Normal\" (18.5 up to 25), \"Overweight\" (25 up to 30), or \"Obese\" (30 and above).\n\nFor example, a weight of 70 kilograms and a height of 1.75 meters produces a BMI of approximately 22.86, which falls in the \"Normal\" category.",
"hints": [
"Body Mass Index is calculated as weight in kilograms divided by the square of height in meters.",
"Once the BMI value itself has been calculated, it needs to be checked against a series of standard threshold ranges to determine which category it falls into.",
"Checking the lowest threshold first, then progressively higher ones, means each check only needs to compare against its own upper bound — by the time a later check runs, every lower category has already been ruled out."
],
"difficulty": 2,
"xp_reward": 110
},
{
"slug": "python-practical-bubble-sort",
"module": "python-practicals",
"title": "Mini-Project: Sorting From Scratch (Bubble Sort)",
"func_name": "bubble_sort_ascending",
"return_type": "list",
"param_types": [
"list"
],
"param_names": [
"numbers"
],
"statement": "**Sorting algorithms** are fundamental to computer science. Implementing a sorting algorithm from scratch — rather than calling a built-in function — builds deep understanding of how data organization actually works.\n\nIn this challenge, your task is to implement the **bubble sort** algorithm. This technique repeatedly steps through a list, compares adjacent elements, and swaps them if they are in the wrong order. After each full pass, the next largest element \"bubbles up\" to its correct position at the end. You must not use Python's built-in `sort()` or `sorted()`.\n\nFor example:\n\n- Sorting **[5, 3, 8, 1, 2]** using bubble sort produces **[1, 2, 3, 5, 8]**.\n- Sorting **[1, 2, 3, 4, 5]** (already sorted) produces **[1, 2, 3, 4, 5]** with no swaps needed.\n- Sorting **[]** or **[1]** produces the same list unchanged.\n\nYour function should return a new list sorted in ascending order.\n\nThis exercise reinforces several important programming concepts:\n\n- Implementing **comparison-based sorting** from scratch.\n- Using **nested loops** for iterative refinement.\n- Understanding **swap operations** and temporary variables.\n- Recognizing **algorithm efficiency** and termination conditions.\n\nBubble sort, while not the most efficient for large datasets, is an excellent teaching tool for understanding the fundamental concepts behind all comparison-based sorting algorithms.",
"original_statement": "Understanding how sorting actually works under the hood, rather than just calling a built-in function, is one of the most valuable exercises for building real algorithmic intuition.\n\nWrite a function that sorts a list of numbers into ascending order using the bubble sort technique — repeatedly comparing neighboring elements and swapping them if they are out of order — without using Python's built-in `sort()` or `sorted()`.\n\nFor example, the list containing 5, 3, 8, 1, and 2, sorted using this technique, becomes 1, 2, 3, 5, and 8.",
"hints": [
"The core idea is to repeatedly compare two neighboring elements and swap them if they are in the wrong order, without ever relying on Python's own built-in sort() method.",
"One full pass through the list, comparing and swapping every neighboring pair along the way, bubbles the single largest remaining value all the way to the end of the unsorted portion.",
"After each full pass, one more element at the end of the list is guaranteed to be in its final, correct position, so the next pass never needs to look at it again."
],
"difficulty": 3,
"xp_reward": 150
},
{
"slug": "python-practical-budget-tracker",
"module": "python-practicals",
"title": "Mini-Project: Personal Budget Tracker",
"func_name": "calculate_budget_balance",
"return_type": "float",
"param_types": [
"list",
"list"
],
"param_names": [
"incomes",
"expenses"
],
"statement": "**Financial calculations** are among the most practical applications of programming. Tracking income and expenses to compute a balance is a core feature of budgeting and accounting software.\n\nIn this challenge, your task is to calculate the overall balance for a personal budget. Given a list of income amounts and a list of expense amounts, compute the net balance — total income minus total expenses — rounded to two decimal places.\n\nFor example:\n\n- **Income: [1000.00, 500.00]** and **expenses: [200.00, 150.00, 50.00]** produce a balance of **1100.00**.\n- **Income: [500.00]** and **expenses: [600.00]** produce a balance of **-100.00** (overspent).\n- **Income: []** and **expenses: []** produce a balance of **0.00**.\n\nYour function should return the balance as a floating-point number rounded to two decimal places.\n\nThis exercise reinforces several important programming concepts:\n\n- **Summing** values across multiple collections.\n- **Subtracting** totals to compute a net value.\n- **Rounding** financial results to a standard precision.\n- Building **money-aware** arithmetic logic.\n\nBudget calculations are used in personal finance apps, business accounting software, expense trackers, and financial planning tools.",
"original_statement": "A personal budgeting app's core feature is simple to describe but genuinely useful: track everything coming in, track everything going out, and report the current balance.\n\nWrite the balance calculation logic for such an app. Given a list of income amounts and a list of expense amounts, calculate the overall balance — total income minus total expenses — rounded to two decimal places.\n\nFor example, income entries of 1000.00 and 500.00 combined with expense entries of 200.00, 150.00, and 50.00 produce a balance of 1100.00.",
"hints": [
"A budget's overall balance is the total of every source of income, minus the total of every recorded expense.",
"Every individual income entry contributes positively to the balance, and every individual expense entry reduces it, regardless of how many entries there are on either side.",
"The final balance should be rounded to two decimal places, matching how real currency amounts are normally displayed."
],
"difficulty": 2,
"xp_reward": 110
},
{
"slug": "python-practical-caesar-decrypt",
"module": "python-practicals",
"title": "Mini-Project: Text Decryption Companion",
"func_name": "decrypt_message",
"return_type": "str",
"param_types": [
"str",
"int"
],
"param_names": [
"message",
"shift"
],
"statement": "**Encryption and decryption** are mirror-image operations. Understanding how to reverse a transformation is just as important as applying it in the first place — and teaches symmetry in algorithm design.\n\nIn this challenge, your task is to implement the **decryption** companion for the Caesar cipher. Given an encrypted message and the shift amount used to encrypt it, recover the original message by shifting every letter backward by that same amount, wrapping around the alphabet and preserving casing.\n\nFor example:\n\n- Decrypting **\"Khoor, Zruog!\"** with shift **3** recovers **\"Hello, World!\"**.\n- Decrypting **\"Bmfy f xywnsl!\"** with shift **5** recovers **\"What a string!\"**.\n- Decrypting **\"Hello\"** with shift **0** returns **\"Hello\"** unchanged.\n\nYour function should return the decrypted message with all letters restored to their original positions.\n\nThis exercise reinforces several important programming concepts:\n\n- Performing the **inverse operation** of an encryption algorithm.\n- Using **modular arithmetic** for alphabet wrapping.\n- **Preserving casing** during character transformations.\n- Leaving **non-letter characters** untouched.\n\nDecryption algorithms are fundamental to data security, secure communications, password storage, and information protection systems.",
"original_statement": "Every encryption technique needs a matching way to reverse it, or the encoded message would be permanently unreadable. This project builds the companion decryption function for the Caesar cipher.\n\nWrite a text decryption function. Given a message that was encrypted using the Caesar cipher with a specific shift amount, recover and return the original message by shifting every letter backward by that same amount, wrapping around the alphabet as needed and preserving casing exactly.\n\nFor example, decrypting \"Khoor, Zruog!\" with a shift of 3 recovers the original message, \"Hello, World!\".",
"hints": [
"Decrypting a Caesar-shifted message is really the exact same shifting operation as encrypting it, just performed with the shift amount reversed.",
"Shifting backward by a given amount is mathematically identical to shifting forward by that same amount subtracted from the full alphabet length, which sidesteps needing to handle negative shift values as a completely separate case.",
"A message that was encrypted with a particular shift should, when decrypted with that exact same shift, come back out exactly as it started, letter for letter and character for character."
],
"difficulty": 2,
"xp_reward": 110
},
{
"slug": "python-practical-caesar-encrypt",
"module": "python-practicals",
"title": "Mini-Project: Text Encryption Generator",
"func_name": "encrypt_message",
"return_type": "str",
"param_types": [
"str",
"int"
],
"param_names": [
"message",
"shift"
],
"statement": "The **Caesar cipher** is one of the oldest known encryption techniques, dating back to ancient Rome. Despite its simplicity, it introduces core concepts that carry forward to modern cryptography.\n\nIn this challenge, your task is to implement a Caesar cipher encryption function. Given a message and a shift amount, replace every letter with the letter that many positions later in the alphabet, wrapping back to the beginning after 'z' or 'Z'. Preserve the original casing of each letter and leave non-letter characters (spaces, punctuation, digits) unchanged.\n\nFor example:\n\n- Encrypting **\"Hello, World!\"** with shift **3** produces **\"Khoor, Zruog!\"**.\n- Encrypting **\"abc\"** with shift **1** produces **\"bcd\"**.\n- Encrypting **\"xyz\"** with shift **3** wraps around to produce **\"abc\"**.\n\nYour function should return the encrypted message with all letters shifted and non-letters preserved.\n\nThis exercise reinforces several important programming concepts:\n\n- Using **character codes** and arithmetic for letter shifting.\n- Applying the **modulo operator** for wrap-around behavior.\n- **Preserving casing** during character transformation.\n- **Selectively transforming** only certain characters in a string.\n\nThe Caesar cipher introduces fundamental ideas about encryption that apply to more complex cryptographic systems used in secure communications today.",
"original_statement": "This project recreates one of the oldest known encryption techniques, the Caesar cipher, which encodes a message by shifting every letter forward through the alphabet by a fixed amount.\n\nWrite a text encryption generator. Given a message and a shift amount, replace every letter in the message with the letter that many positions later in the alphabet, wrapping back around to the start if the shift goes past 'z' or 'Z'. Preserve the original casing and leave non-letter characters unchanged.\n\nFor example, encrypting \"Hello, World!\" with a shift of 3 produces \"Khoor, Zruog!\" — each letter has moved 3 positions forward, while punctuation remains untouched.",
"hints": [
"Only letters should actually be shifted — spaces, punctuation, and any other non-letter characters should pass through completely unchanged.",
"Preserving the original casing of each letter matters: an uppercase letter should shift to another uppercase letter, and a lowercase letter should shift to another lowercase letter.",
"The alphabet wraps around: shifting the letter z forward should cycle back around to the beginning of the alphabet rather than falling off the end, which is exactly what the modulo operator is for."
],
"difficulty": 2,
"xp_reward": 110
},
{
"slug": "python-practical-click-counter",
"module": "python-practicals",
"title": "Mini-Project: Click Counter App Logic",
"func_name": "simulate_click_counter",
"return_type": "int",
"param_types": [
"list"
],
"param_names": [
"actions"
],
"statement": "Counters are commonly used to track values that change over time, such as button clicks, scores, inventory levels, or user interactions. \nBy processing a sequence of actions in order, you can determine the final state of the counter.\n\nIn this challenge, your task is to process a list of counter actions. Each action will be one of the following:\n\n- `increment` — Increase the counter by `1`.\n- `decrement` — Decrease the counter by `1`.\n- `reset` — Set the counter back to `0`.\n\nStarting from an initial count of `0`, apply each action in the order it appears and determine the final value of the counter.\n\nYour function should return the counter's final value after all actions have been processed.\n\nThis exercise reinforces several important programming concepts:\n\n- Iterating through a **list** of instructions.\n- Updating a value based on different conditions.\n- Using **conditional statements** to control program flow.\n- Maintaining and modifying a running state throughout a sequence of operations.\n\nProcessing sequential actions is a common programming pattern used in interactive applications, games, event-driven systems, and state management.",
"original_statement": "Counters are commonly used to track values that change over time, such as button clicks, scores, inventory levels, or user interactions. \nBy processing a sequence of actions in order, you can determine the final state of the counter.\n\nIn this challenge, your task is to process a list of counter actions. Each action will be one of the following:\n\n- `increment` — Increase the counter by `1`.\n- `decrement` — Decrease the counter by `1`.\n- `reset` — Set the counter back to `0`.\n\nStarting from an initial count of `0`, apply each action in the order it appears and determine the final value of the counter.\n\nYour function should return the counter's final value after all actions have been processed.\n\nThis exercise reinforces several important programming concepts:\n\n- Iterating through a **list** of instructions.\n- Updating a value based on different conditions.\n- Using **conditional statements** to control program flow.\n- Maintaining and modifying a running state throughout a sequence of operations.\n\nProcessing sequential actions is a common programming pattern used in interactive applications, games, event-driven systems, and state management.",
"hints": [
"The function processes a list of string commands one at a time, maintaining a running count throughout.",
"The three possible commands cover every operation a simple counter needs: increase, decrease, and reset.",
"Starting from zero and processing commands in order exactly mirrors how a real click-counter app behaves over time."
],
"difficulty": 1,
"xp_reward": 70
},
{
"slug": "python-practical-countdown-calculator",
"module": "python-practicals",
"title": "Mini-Project: Date Countdown Calculator",
"func_name": "days_between_dates",
"return_type": "int",
"param_types": [
"str",
"str"
],
"param_names": [
"date1",
"date2"
],
"statement": "Working with **dates and calendars** involves complex rules — varying month lengths, leap years, and time zones. Python's `datetime` module handles all of this complexity, making date arithmetic straightforward.\n\nIn this challenge, your task is to calculate the number of days between two dates. Given two date strings in \"YYYY-MM-DD\" format, compute the absolute difference in days. The result should always be non-negative, regardless of which date comes first chronologically.\n\nFor example:\n\n- Between **\"2024-01-01\"** and **\"2024-01-10\"** there are **9** days.\n- Between **\"2024-03-01\"** and **\"2024-03-01\"** (same date) there are **0** days.\n- Between **\"2024-12-25\"** and **\"2024-01-01\"** there are **359** days (absolute value).\n\nYour function should return the number of days as an integer.\n\nThis exercise reinforces several important programming concepts:\n\n- Using Python's **`datetime` module** for date parsing and arithmetic.\n- Computing **`timedelta`** differences between dates.\n- Using **`abs()`** to guarantee non-negative results.\n- Handling **calendar complexity** through built-in libraries.\n\nDate difference calculations are used in booking systems, project planning, age calculation, countdown apps, and deadline tracking.",
"original_statement": "Counting down (or up) to an important date is a genuinely useful little tool, and a great introduction to Python's datetime module, which handles all of the tricky calendar arithmetic (leap years, varying month lengths, and so on) automatically.\n\nWrite a countdown calculator. Given two dates, each formatted as a string in \"YYYY-MM-DD\" form, calculate the number of days between them. The result should always be a non-negative number of days, regardless of which of the two dates comes first chronologically.\n\nFor example, the dates \"2024-01-01\" and \"2024-01-10\" are 9 days apart.",
"hints": [
"Python's built-in datetime module can parse a date string like \"2024-01-01\" directly into an actual date object that supports arithmetic, rather than needing to manually split the string apart and calculate calendar math by hand.",
"Subtracting one datetime object from another produces a timedelta object, which has a .days attribute giving the exact number of whole days between them.",
"The two given dates might be provided in either chronological order, so wrapping the final result in an absolute-value function guarantees a sensible, non-negative day count regardless of which date comes first."
],
"difficulty": 3,
"xp_reward": 150
},
{
"slug": "python-practical-countdown-formatter",
"module": "python-practicals",
"title": "Mini-Project: Countdown Timer Display Formatter",
"func_name": "format_countdown_timer",
"return_type": "str",
"param_types": [
"int"
],
"param_names": [
"total_seconds"
],
"statement": "**Time format conversion** is a common task in application development. Displaying a raw number of seconds as a human-readable hours:minutes:seconds string requires division, remainder, and zero-padded formatting.\n\nIn this challenge, your task is to convert a total number of seconds into a formatted time string in \"HH:MM:SS\" format, with each component padded to exactly two digits using leading zeros where necessary.\n\nFor example:\n\n- **3725** seconds formats as **\"01:02:05\"** (1 hour, 2 minutes, 5 seconds).\n- **0** seconds formats as **\"00:00:00\"**.\n- **3661** seconds formats as **\"01:01:01\"** (1 hour, 1 minute, 1 second).\n\nYour function should return the formatted time string.\n\nThis exercise reinforces several important programming concepts:\n\n- Using **integer division** (`//`) to extract whole units.\n- Using the **modulo operator** (`%`) to find remainders.\n- **Zero-padding** values with `str.zfill()` or format strings.\n- Converting between **raw units and display format**.\n\nTime formatting is used in video players, cooking timers, workout apps, dashboards, and any application that displays durations.",
"original_statement": "Every countdown timer, whether in a cooking app, a workout app, or a game, needs to convert a raw number of seconds into a familiar hours-minutes-seconds display.\n\nWrite the display-formatting logic for such a timer. Given a total number of seconds remaining, format it as a string in the form \"HH:MM:SS\", with each component padded to exactly two digits using a leading zero where necessary.\n\nFor example, 3725 seconds is exactly 1 hour, 2 minutes, and 5 seconds, so it should be formatted as \"01:02:05\".",
"hints": [
"An hour is 3600 seconds, so the number of whole hours in a duration is found by integer-dividing the total seconds by 3600.",
"Once the hours have been accounted for, the number of whole minutes remaining is found the same way, using whatever seconds are left over after removing the hours.",
"Formatting each of the three components (hours, minutes, seconds) with a fixed width of two digits, padding with a leading zero where needed, produces the familiar HH:MM:SS display."
],
"difficulty": 1,
"xp_reward": 70
},
{
"slug": "python-practical-dice-average",
"module": "python-practicals",
"title": "Mini-Project: Dice Roll Statistics Tracker",
"func_name": "calculate_average_roll",
"return_type": "float",
"param_types": [
"list"
],
"param_names": [
"rolls"
],
"statement": "Calculating an **average** is one of the most common operations performed on numerical data. By combining the values in a collection and dividing by the total number of items, you can determine a value that represents the overall result.\n\nIn this challenge, your task is to calculate the **average** of a list of dice roll results. The average should be rounded to **two decimal places**. If the list contains no values, your function should return `0.0`.\n\nYour function should return the average value of all recorded dice rolls.\n\nThis exercise reinforces several important programming concepts:\n\n- Working with **lists** of numeric values.\n- Calculating the **sum** and **average** of a collection.\n- Handling edge cases, such as an empty list.\n- Rounding numeric results to a specified number of decimal places.\n\nComputing averages is a fundamental programming technique used in statistics, analytics, reporting, gaming, and many other real-world applications.",
"original_statement": "Calculating an **average** is one of the most common operations performed on numerical data. By combining the values in a collection and dividing by the total number of items, you can determine a value that represents the overall result.\n\nIn this challenge, your task is to calculate the **average** of a list of dice roll results. The average should be rounded to **two decimal places**. If the list contains no values, your function should return `0.0`.\n\nYour function should return the average value of all recorded dice rolls.\n\nThis exercise reinforces several important programming concepts:\n\n- Working with **lists** of numeric values.\n- Calculating the **sum** and **average** of a collection.\n- Handling edge cases, such as an empty list.\n- Rounding numeric results to a specified number of decimal places.\n\nComputing averages is a fundamental programming technique used in statistics, analytics, reporting, gaming, and many other real-world applications.",
"hints": [
"The average of a set of dice rolls is simply the total of every roll divided by how many rolls there were.",
"A completely empty history of rolls has no meaningful average to report, so that case needs to be guarded against before any division is attempted.",
"As with any statistic meant for display, the final average should be rounded to two decimal places rather than left with excessive decimal precision."
],
"difficulty": 1,
"xp_reward": 70
},
{
"slug": "python-practical-guess-feedback",
"module": "python-practicals",
"title": "Mini-Project: Number-Guessing Game Feedback",
"func_name": "guess_feedback",
"return_type": "str",
"param_types": [
"int",
"int"
],
"param_names": [
"secret",
"guess"
],
"statement": "**Comparison logic** with three possible outcomes is a fundamental programming pattern. Number-guessing games provide a simple, intuitive context for practicing conditional branching.\n\nIn this challenge, your task is to implement the feedback system for a number-guessing game. Given a secret number and the player's guess, return \"higher\" if the guess is too low (the player needs to guess higher), \"lower\" if the guess is too high, or \"correct\" if the guess is exactly right.\n\nFor example:\n\n- Secret **50** and guess **30** returns **\"higher\"** (guess 30 is too low).\n- Secret **50** and guess **75** returns **\"lower\"** (guess 75 is too high).\n- Secret **50** and guess **50** returns **\"correct\"**.\n\nYour function should return the appropriate feedback string.\n\nThis exercise reinforces several important programming concepts:\n\n- Using **conditional statements** to compare two values.\n- Providing **directional feedback** that guides the user.\n- Implementing **exact-match detection**.\n- Covering all three possible **comparison outcomes**.\n\nComparison-based feedback is used in games, search algorithms, optimization problems, and any interactive system where user input needs evaluation.",
"original_statement": "The number-guessing game is a beginner classic: the program picks a secret number, and the player guesses repeatedly, receiving feedback after each attempt until they find it.\n\nWrite the feedback logic for such a game. Given the secret number and the player's current guess, return \"higher\" if the player needs to guess a higher number next, \"lower\" if they need to guess a lower number, or \"correct\" if they have guessed exactly right.\n\nFor example, with a secret number of 50, a guess of 30 should receive the feedback \"higher\", since the player needs to guess higher to get closer to 50.",
"hints": [
"There are exactly three possible relationships between the guess and the secret number: the guess is too low, too high, or exactly right.",
"If the guess is lower than the secret number, the player needs to guess higher next time — the feedback message should point the player in the direction of the correct answer.",
"The exact-match case should be checked in a way that is reached only once the other two possibilities have already been ruled out, since a value cannot simultaneously be too low and too high."
],
"difficulty": 2,
"xp_reward": 110
},
{
"slug": "python-practical-hangman-display",
"module": "python-practicals",
"title": "Mini-Project: Hangman Word Display",
"func_name": "hangman_display",
"return_type": "str",
"param_types": [
"str",
"list"
],
"param_names": [
"secret_word",
"guessed_letters"
],
"statement": "**String transformation** based on character-by-character conditions is a common pattern in text-based games and data processing. Revealing information selectively based on user input creates engaging interactive experiences.\n\nIn this challenge, your task is to implement the display logic for a Hangman word-guessing game. Given the secret word and a list of letters the player has guessed so far, return a string where every correctly guessed letter is shown in its proper position and every not-yet-guessed letter is replaced by an underscore.\n\nFor example:\n\n- Word **\"python\"** with guessed letters **[\"p\", \"y\", \"z\"]** displays as **\"py____\"**.\n- Word **\"hello\"** with guessed letters **[\"h\", \"e\"]** displays as **\"he___\"**.\n- Word **\"hello\"** with guessed letters **[\"h\", \"e\", \"l\", \"o\"]** displays as **\"hello\"**.\n\nYour function should return the display string with underscores masking unguessed letters.\n\nThis exercise reinforces several important programming concepts:\n\n- **Iterating** through each character of a string.\n- **Membership testing** in a list of guessed letters.\n- **Building** a result string character by character.\n- Handling **duplicate letters** correctly.\n\nSelective character display is used in word games, password masking, text-reveal animations, and any application where information is progressively revealed.",
"original_statement": "The Hangman word-guessing game constantly needs to redraw its display: revealing letters the player has already guessed correctly, and masking every letter they have not guessed yet.\n\nWrite the display logic for a Hangman game. Given the secret word and a list of letters the player has guessed so far, return a string showing every correctly guessed letter in its proper position, with every not-yet-guessed letter replaced by an underscore.\n\nFor example, the word \"python\" with guessed letters \"p\", \"y\", and \"z\" should display as \"py____\", since only the letters \"p\" and \"y\" have been guessed so far.",
"hints": [
"Every letter in the secret word needs to be checked individually against the set of letters guessed so far, since a letter might have been guessed while others have not.",
"A letter that has already been guessed should be revealed in the display exactly as it is in the word; any letter that has not been guessed yet should be masked as a single underscore.",
"The relative positions of the letters matter, including any duplicate letters — every occurrence of a correctly guessed letter should be revealed everywhere it appears in the word."
],
"difficulty": 3,
"xp_reward": 150
},
{
"slug": "python-practical-length-converter",
"module": "python-practicals",
"title": "Mini-Project: Length Unit Converter",
"func_name": "convert_length",
"return_type": "float",
"param_types": [
"float",
"str"
],
"param_names": [
"value",
"target_unit"
],
"statement": "**Unit conversion** is a practical programming task that appears in countless applications. A single conversion factor connects two measurement systems, and the direction of conversion determines whether you multiply or divide.\n\nIn this challenge, your task is to implement a length converter that converts between inches and centimeters. Given a numeric value and a target unit (\"cm\" or \"in\"), convert the value into that target unit, rounded to two decimal places. Assume the given value is expressed in the opposite unit.\n\nFor example:\n\n- Converting **10.0** to **\"cm\"** returns **25.4** (1 inch = 2.54 cm).\n- Converting **25.4** to **\"in\"** returns **10.0** (the inverse operation).\n- Converting **0.0** to **\"cm\"** returns **0.0**.\n\nYour function should return the converted value rounded to two decimal places.\n\nThis exercise reinforces several important programming concepts:\n\n- Using a **conversion factor** to translate between units.\n- **Conditionally** multiplying or dividing based on target unit.\n- **Rounding** results to a specified precision.\n- Understanding **inverse operations** in measurement conversion.\n\nUnit conversion is used in scientific computing, engineering applications, cooking apps, mapping software, and international commerce.",
"original_statement": "Extending the idea of a unit converter to a different kind of measurement is a great way to notice how much of the underlying structure stays the same, even though the actual conversion formula changes completely.\n\nWrite the underlying conversion logic for a length converter. Given a value and a target unit — either \"cm\" for centimeters or \"in\" for inches — convert the value into that target unit, rounded to two decimal places, assuming the given value is expressed in whichever unit is not the target.\n\nFor example, converting the value 10.0 to \"cm\" produces 25.4, since one inch equals exactly 2.54 centimeters. Converting the value 25.4 to \"in\" produces exactly 10.0 again.",
"hints": [
"One inch is defined as exactly 2.54 centimeters, which is the single conversion factor this entire problem is built around.",
"Converting inches to centimeters means multiplying by that factor; converting centimeters to inches means dividing by it — the two operations are exact inverses of each other.",
"As with the temperature converter, the result should be rounded to two decimal places for a clean, realistic display."
],
"difficulty": 1,
"xp_reward": 70
},
{
"slug": "python-practical-library-due-date",
"module": "python-practicals",
"title": "Mini-Project: Library Book Due Date Calculator",
"func_name": "calculate_due_date",
"return_type": "str",
"param_types": [
"str",
"int"
],
"param_names": [
"checkout_date",
"loan_days"
],
"statement": "**Date arithmetic** is essential in many real-world applications. Calculating due dates, expiration dates, and deadlines requires correctly handling month boundaries, year boundaries, and varying month lengths.\n\nIn this challenge, your task is to calculate a future due date given a checkout date and a loan period in days. Given a starting date in \"YYYY-MM-DD\" format and the number of days in the loan period, compute and return the due date in the same date format.\n\nFor example:\n\n- Checkout **\"2024-01-20\"** with a **14-day** loan produces a due date of **\"2024-02-03\"**.\n- Checkout **\"2024-12-20\"** with a **20-day** loan produces **\"2025-01-09\"** (crosses into the new year).\n- Checkout **\"2024-02-28\"** with a **1-day** loan produces **\"2024-02-29\"** (correctly handles leap year 2024).\n\nYour function should return the due date as a string in \"YYYY-MM-DD\" format.\n\nThis exercise reinforces several important programming concepts:\n\n- Using Python's **`datetime` module** for date arithmetic.\n- Adding a **`timedelta`** to a date object.\n- Formatting dates back to **string representation**.\n- Handling **calendar complexities** through built-in libraries.\n\nDue date calculations are used in library systems, rental services, subscription billing, project management, and legal deadline tracking.",
"original_statement": "Library systems, equipment rental services, and countless other applications need to calculate a future due date by adding a fixed loan period onto a starting date, correctly handling every month and year boundary along the way.\n\nWrite a due-date calculator. Given a checkout date formatted as \"YYYY-MM-DD\" and a loan period in days, calculate the due date and return it in that same date format.\n\nFor example, a book checked out on \"2024-01-20\" with a 14-day loan period is due on \"2024-02-03\" — the calculation correctly carries the date over from January into February.",
"hints": [
"Adding a number of days onto a specific calendar date requires genuine calendar arithmetic, correctly handling month boundaries (and even year boundaries) rather than simple digit addition.",
"Python's datetime module supports adding a timedelta representing a number of days directly onto a parsed date, producing a new, correctly calculated date.",
"The result needs to be formatted back into the same \"YYYY-MM-DD\" string style as the original input, so the output stays consistent with how dates are represented throughout this problem."
],
"difficulty": 3,
"xp_reward": 150
},
{
"slug": "python-practical-mad-libs",
"module": "python-practicals",
"title": "Mini-Project: Mad Libs Story Filler",
"func_name": "fill_mad_libs_template",
"return_type": "str",
"param_types": [
"str",
"list"
],
"param_names": [
"template",
"words"
],
"statement": "**String substitution** is a fundamental text processing operation. Replacing placeholders in a template with provided values is used everywhere from form letters to code generation.\n\nIn this challenge, your task is to implement a Mad Libs story filler. Given a story template containing numbered placeholders like \"{0}\", \"{1}\", etc., and a list of words to fill them in with, replace each placeholder with the word at the matching position in the list.\n\nFor example:\n\n- Template **\"The {0} jumped over the {1}.\"** with words **[\"cat\", \"moon\"]** produces **\"The cat jumped over the moon.\"**.\n- Template **\"Once upon a {0}, there was a {1} who loved {2}.\"** with words **[\"time\", \"princess\", \"dancing\"]** produces **\"Once upon a time, there was a princess who loved dancing.\"**.\n- Template **\"Hello, {0}!\"** with words **[\"world\"]** produces **\"Hello, world!\"**.\n\nYour function should return the completed story string.\n\nThis exercise reinforces several important programming concepts:\n\n- Using **`str.replace()`** for placeholder substitution.\n- **Iterating** through placeholders and replacement values together.\n- Building a result string by **progressive replacement**.\n- Understanding **string immutability** in Python.\n\nTemplate substitution is used in document generation, email templates, reporting systems, code generation, and content management systems.",
"original_statement": "Mad Libs — the game where you supply random words to fill in the blanks of a story without knowing what it says, producing a silly result — is a lighthearted, genuinely fun first project for practicing string templates and substitution.\n\nWrite a Mad Libs filler. Given a story template containing numbered placeholders in the form \"{0}\", \"{1}\", and so on, and a list of words to fill them in with, replace each placeholder with the word at the matching position in the list, and return the completed story.\n\nFor example, the template \"The {0} jumped over the {1}.\" filled in with the words \"cat\" and \"moon\" produces \"The cat jumped over the moon.\"",
"hints": [
"The template contains numbered placeholders like {0} and {1}, each marking exactly where one of the supplied words should be inserted.",
"Every placeholder needs to be replaced with the word at the matching position in the supplied word list — placeholder {0} with the first word, {1} with the second, and so on.",
"Processing the placeholders one at a time, replacing each one in the template before moving on to the next, builds up the final filled-in story correctly regardless of how many blanks the template contains."
],
"difficulty": 3,
"xp_reward": 150
},
{
"slug": "python-practical-personality-quiz",
"module": "python-practicals",
"title": "Mini-Project: \"Which Avenger Are You?\" Result Picker",
"func_name": "determine_personality_result",
"return_type": "str",
"param_types": [
"list"
],
"param_names": [
"scores"
],
"statement": "**Scoring and ranking** are fundamental data processing tasks. Personality quizzes and recommendation systems both rely on the same underlying logic: tally scores for each option and pick the winner.\n\nIn this challenge, your task is to implement the result-picking logic for a personality quiz. Given a list of four scores — representing Iron Man, Captain America, Thor, and Hulk in that order — determine which character has the highest score and return their name.\n\nFor example:\n\n- Scores **[3, 5, 2, 1]** indicate **Captain America** (score 5) is the closest match.\n- Scores **[8, 1, 3, 2]** indicate **Iron Man** (score 8) is the closest match.\n- Scores **[1, 1, 1, 1]** (all tied) indicate **Iron Man** is the closest match (first among equals).\n\nYour function should return the name of the character with the highest score.\n\nThis exercise reinforces several important programming concepts:\n\n- Finding the **maximum value** in a list.\n- **Tracking the index** of the maximum value.\n- **Mapping indices** to corresponding labels.\n- Handling **ties** by selecting the first occurrence.\n\nMaximum-based selection is used in recommendation systems, voting applications, personality assessments, and any system that ranks multiple candidates.",
"original_statement": "\"Which character are you?\" personality quizzes are a genuinely fun beginner project: behind the playful presentation, they are really just a straightforward scoring system that tracks points for each possible outcome and reports whichever one accumulated the most.\n\nWrite the result-picking logic for such a quiz, matching a user's answers to one of four Avengers: Iron Man, Captain America, Thor, and Hulk. Given a list of four scores — one for each character, in that order — determine which character the user matches best by returning the name of the character with the highest score.\n\nFor example, scores of 3, 5, 2, and 1 indicate the user matches Captain America most closely, since that score is the highest.",
"hints": [
"Behind the scenes, a personality quiz like this tallies up a running score for each possible result as the user answers questions, and the highest-scoring result at the end becomes the final outcome.",
"The four possible results correspond, in order, to the four scores provided — the first score belongs to the first character, the second score to the second character, and so on.",
"Scanning through the scores while tracking both the best score seen so far and which character it belongs to, updating only when a strictly higher score appears, correctly picks out the single highest-scoring result."
],
"difficulty": 4,
"xp_reward": 190
},
{
"slug": "python-practical-quiz-score",
"module": "python-practicals",
"title": "Mini-Project: Interactive Quiz Scorer",
"func_name": "calculate_quiz_score",
"return_type": "int",
"param_types": [
"list",
"list"
],
"param_names": [
"submitted_answers",
"correct_answers"
],
"statement": "**Comparing parallel lists** position by position is a common data processing pattern. Grading systems, survey analysis, and test scoring all rely on matching answers against answer keys.\n\nIn this challenge, your task is to implement the scoring logic for a quiz application. Given a list of a quiz-taker's submitted answers and a matching list of correct answers, calculate how many questions were answered correctly by comparing them position by position.\n\nFor example:\n\n- Submitted **[\"A\", \"B\", \"C\"]** against correct **[\"A\", \"B\", \"D\"]** produces a score of **2**.\n- Submitted **[\"A\", \"B\", \"C\"]** against correct **[\"A\", \"B\", \"C\"]** produces a perfect score of **3**.\n- Submitted **[\"A\", \"B\", \"C\"]** against correct **[\"D\", \"E\", \"F\"]** produces a score of **0**.\n\nYour function should return the number of correct answers as an integer.\n\nThis exercise reinforces several important programming concepts:\n\n- **Zipping** or pairing two lists for parallel iteration.\n- Comparing **corresponding elements** position by position.\n- **Counting** matches with an accumulator.\n- Handling **equal-length** list comparison.\n\nParallel list comparison is used in automated grading, survey processing, data validation, and any system that checks answers against a key.",
"original_statement": "Every interactive quiz application, however elaborate its interface, comes down to the same core logic underneath: compare what the user answered against the correct answers, and tally up the score.\n\nWrite the scoring logic for a quiz application. Given a list of a quiz-taker's submitted answers and a matching list of correct answers, calculate how many questions were answered correctly.\n\nFor example, submitted answers of \"A\", \"B\", and \"C\" compared against correct answers of \"A\", \"B\", and \"D\" produce a score of 2, since the first two answers match and the third does not.",
"hints": [
"Every one of a quiz-taker's answers needs to be compared against the correct answer for that same question, position by position.",
"Pairing up the two parallel lists — the submitted answers and the correct answers — position by position is exactly what is needed before any comparison can happen.",
"The final score is simply a running count of how many of those position-by-position comparisons came out equal."
],
"difficulty": 2,
"xp_reward": 110
},
{
"slug": "python-practical-rock-paper-scissors",
"module": "python-practicals",
"title": "Mini-Project: Rock-Paper-Scissors Referee",
"func_name": "determine_rps_winner",
"return_type": "str",
"param_types": [
"str",
"str"
],
"param_names": [
"player1",
"player2"
],
"statement": "Rock-paper-scissors is a classic game that is often used to practice **conditional logic** and decision-making in programming.\n\nEach round follows a simple set of rules that determine the winner based on the choices made by two players.\n\nIn this challenge, your task is to implement the referee logic for a two-player game of **rock-paper-scissors**.\nEach player will choose one of three possible moves: `rock`, `paper`, or `scissors`.\n\nYour function should compare both moves and return the appropriate result:\n\n- `\"Player 1\"` if the first player's move wins.\n- `\"Player 2\"` if the second player's move wins.\n- `\"Tie\"` if both players choose the same move.\n\nThis exercise reinforces several important programming concepts:\n\n- Using **conditional statements** to evaluate multiple outcomes.\n- Comparing values to determine a result.\n- Implementing rule-based decision logic.\n- Translating real-world game rules into clear and maintainable code.\n\nBuilding simple game logic is an excellent way to develop problem-solving skills and practice writing code that handles multiple conditions correctly.",
"original_statement": "Rock-paper-scissors is a classic game that is often used to practice **conditional logic** and decision-making in programming.\n\nEach round follows a simple set of rules that determine the winner based on the choices made by two players.\n\nIn this challenge, your task is to implement the referee logic for a two-player game of **rock-paper-scissors**.\nEach player will choose one of three possible moves: `rock`, `paper`, or `scissors`.\n\nYour function should compare both moves and return the appropriate result:\n\n- `\"Player 1\"` if the first player's move wins.\n- `\"Player 2\"` if the second player's move wins.\n- `\"Tie\"` if both players choose the same move.\n\nThis exercise reinforces several important programming concepts:\n\n- Using **conditional statements** to evaluate multiple outcomes.\n- Comparing values to determine a result.\n- Implementing rule-based decision logic.\n- Translating real-world game rules into clear and maintainable code.\n\nBuilding simple game logic is an excellent way to develop problem-solving skills and practice writing code that handles multiple conditions correctly.",
"hints": [
"Before checking who wins, first rule out the simplest case: both players choosing the exact same move always results in a tie.",
"A small lookup describing what each move beats (rock beats scissors, scissors beats paper, paper beats rock) captures the entire rule set of the game in one place.",
"If player one's move does not beat player two's move, and it is not a tie, then player two must be the winner by elimination."
],
"difficulty": 1,
"xp_reward": 70
},
{
"slug": "python-practical-selection-sort",
"module": "python-practicals",
"title": "Mini-Project: Sorting From Scratch (Selection Sort)",
"func_name": "selection_sort_ascending",
"return_type": "list",
"param_types": [
"list"
],
"param_names": [
"numbers"
],
"statement": "**Selection sort** is a fundamental sorting algorithm that works by repeatedly finding the minimum element from the unsorted portion of a list and moving it to the front. Understanding different sorting strategies builds deeper algorithmic intuition.\n\nIn this challenge, your task is to implement the **selection sort** algorithm without using Python's built-in `sort()` or `sorted()`. Scan the unsorted portion of the list for the smallest remaining value, swap it into the correct position, and repeat until the entire list is sorted.\n\nFor example:\n\n- Sorting **[64, 25, 12, 22, 11]** produces **[11, 12, 22, 25, 64]**.\n- Sorting **[1, 2, 3, 4, 5]** (already sorted) produces **[1, 2, 3, 4, 5]**.\n- Sorting **[]** or **[42]** returns the list unchanged.\n\nYour function should return a new list sorted in ascending order.\n\nThis exercise reinforces several important programming concepts:\n\n- Using **nested loops** for repeated scanning.\n- Finding the **minimum value** in a sublist.\n- Performing **swap operations** with index tracking.\n- Understanding the **algorithm structure** of in-place sorting.\n\nSelection sort teaches the fundamental \"find and place\" strategy that underlies more advanced algorithms used in data processing and database systems.",
"original_statement": "This project builds a second sorting algorithm from scratch, using a completely different strategy than bubble sort, which is a great way to notice that \"sorting\" is not just one single technique.\n\nWrite a function that sorts a list of numbers into ascending order using the selection sort technique — repeatedly finding the minimum value in the unsorted portion of the list and moving it into place — without using Python's built-in `sort()` or `sorted()`.\n\nFor example, the list containing 64, 25, 12, 22, and 11, sorted using this technique, becomes 11, 12, 22, 25, and 64.",
"hints": [
"This technique repeatedly scans the still-unsorted portion of the list to find its single smallest remaining value, without ever calling Python's built-in sort() method.",
"Once the smallest remaining value has been located, it gets swapped into the front position of the unsorted portion, which grows the sorted portion by exactly one element.",
"Each pass only needs to scan the portion of the list that has not been sorted yet — everything before that point is already known to be in its correct final position."
],
"difficulty": 3,
"xp_reward": 150
},
{
"slug": "python-practical-simple-calculator",
"module": "python-practicals",
"title": "Mini-Project: Simple Calculator Engine",
"func_name": "evaluate_simple_expression",
"return_type": "float",
"param_types": [
"float",
"float",
"str"
],
"param_names": [
"a",
"b",
"operator"
],
"statement": "**Arithmetic operations** are the foundation of all computational mathematics. A calculator engine must handle each operation correctly and guard against error conditions like division by zero.\n\nIn this challenge, your task is to implement the core calculation engine for a simple calculator. Given two numbers and an operator — one of \"+\", \"-\", \"*\", or \"/\" — compute and return the result. If the operator is \"/\" and the second number is zero, return `0.0` instead of attempting the division.\n\nFor example:\n\n- Evaluating **10.0, 3.0, \"/\"** returns approximately **3.3333333333333335** (the standard floating-point result).\n- Evaluating **10.0, 0.0, \"/\"** returns **0.0** (safe division-by-zero handling).\n- Evaluating **5.0, 3.0, \"+\"** returns **8.0**.\n\nYour function should return the computed numeric result.\n\nThis exercise reinforces several important programming concepts:\n\n- Using **conditional branching** to select the correct operation.\n- Handling the **division-by-zero** edge case safely.\n- Working with **floating-point arithmetic**.\n- Building a clean **operator dispatch** structure.\n\nCalculator engines are used in spreadsheet software, financial applications, scientific computing, and every system that performs mathematical computations.",
"original_statement": "Every calculator app, no matter how many advanced features it eventually grows, starts from the same small core: given two numbers and an operator, compute the result.\n\nWrite the calculation engine for a simple calculator. Given two numbers and an operator — one of \"+\", \"-\", \"*\", or \"/\" — compute and return the result of applying that operator to the two numbers. If the operator is \"/\" and the second number is zero, return 0.0 instead of attempting an impossible division.\n\nFor example, evaluating 10.0, 3.0, with the operator \"/\" produces approximately 3.33.",
"hints": [
"Each of the four basic arithmetic operators needs its own branch, since addition, subtraction, multiplication, and division are all fundamentally different operations.",
"Division is the one operator among the four that can fail outright — dividing by zero is mathematically undefined, and needs to be explicitly guarded against before the division is attempted.",
"Rather than letting a division by zero crash the whole calculator, returning a safe, documented fallback value keeps the calculator usable even when it is given an invalid expression to evaluate."
],
"difficulty": 4,
"xp_reward": 190
},
{
"slug": "python-practical-temperature-converter",
"module": "python-practicals",
"title": "Mini-Project: Temperature Converter",
"func_name": "convert_temperature",
"return_type": "float",
"param_types": [
"float",
"str"
],
"param_names": [
"value",
"target_unit"
],
"statement": "**Temperature conversion** is a classic beginner project that teaches conditional logic and formula application. Converting between Fahrenheit and Celsius requires understanding two different mathematical relationships.\n\nIn this challenge, your task is to implement a temperature converter. Given a temperature value and a target unit (\"C\" for Celsius or \"F\" for Fahrenheit), convert the value into that target unit, rounded to two decimal places. Assume the given value is expressed in the opposite unit.\n\nFor example:\n\n- Converting **212.0** to **\"C\"** returns **100.0** (the boiling point of water in Celsius).\n- Converting **100.0** to **\"F\"** returns **212.0** (the inverse conversion).\n- Converting **-40.0** to **\"C\"** returns **-40.0** (the unique point where both scales meet).\n\nYour function should return the converted temperature rounded to two decimal places.\n\nThis exercise reinforces several important programming concepts:\n\n- Applying **different formulas** based on the target unit.\n- Performing **multiplication and division** in the correct order.\n- **Rounding** results to standard precision.\n- Understanding **inverse transformations**.\n\nTemperature conversion is used in weather apps, cooking applications, scientific software, and international commerce.",
"original_statement": "This is a classic first project for getting comfortable with conditional logic and simple mathematical formulas: a converter that translates a temperature reading between Fahrenheit and Celsius in either direction.\n\nWrite the underlying conversion logic for a temperature converter. Given a temperature value and a target unit — either \"C\" for Celsius or \"F\" for Fahrenheit — convert the value into that target unit, rounded to two decimal places. The function should assume the given value is already expressed in whichever unit is not the target.\n\nFor example, converting the value 212.0 to \"C\" produces 100.0, since 212 degrees Fahrenheit is exactly the boiling point of water in Celsius. Converting the value 100.0 to \"F\" produces 212.0.",
"hints": [
"Converting Fahrenheit to Celsius and converting Celsius to Fahrenheit are two different formulas, so the target unit needs to determine which one runs.",
"The standard Fahrenheit-to-Celsius formula subtracts 32 first, then multiplies by five-ninths; the Celsius-to-Fahrenheit formula multiplies by nine-fifths first, then adds 32.",
"The result should be rounded to two decimal places, matching how a real temperature display would show it."
],
"difficulty": 1,
"xp_reward": 70
},
{
"slug": "python-practical-tip-split",
"module": "python-practicals",
"title": "Mini-Project: Restaurant Tip Splitter",
"func_name": "calculate_tip_split",
"return_type": "float",
"param_types": [
"float",
"float",
"int"
],
"param_names": [
"bill_total",
"tip_percent",
"num_people"
],
"statement": "Splitting a bill is a common financial calculation that combines percentages, arithmetic, and rounding. It is a practical problem that demonstrates how simple mathematical operations can be used to solve real-world tasks.\n\nIn this challenge, your task is to calculate how much each person should pay when a bill is split evenly among a group. The total bill should first be increased by the specified **tip percentage**, after which the final amount is divided equally among all participants.\n\nYour function should return the amount each person owes, rounded to **two decimal places**.\n\nThis exercise reinforces several important programming concepts:\n\n- Performing arithmetic calculations with multiple inputs.\n- Calculating **percentages** and applying them to a total.\n- Dividing a value evenly among a group.\n- Rounding decimal values to a specified precision.\n\nBill splitting is a practical programming exercise that introduces financial calculations commonly used in payment systems, budgeting tools, expense trackers, and billing applications.",
"original_statement": "Splitting a bill is a common financial calculation that combines percentages, arithmetic, and rounding. It is a practical problem that demonstrates how simple mathematical operations can be used to solve real-world tasks.\n\nIn this challenge, your task is to calculate how much each person should pay when a bill is split evenly among a group. The total bill should first be increased by the specified **tip percentage**, after which the final amount is divided equally among all participants.\n\nYour function should return the amount each person owes, rounded to **two decimal places**.\n\nThis exercise reinforces several important programming concepts:\n\n- Performing arithmetic calculations with multiple inputs.\n- Calculating **percentages** and applying them to a total.\n- Dividing a value evenly among a group.\n- Rounding decimal values to a specified precision.\n\nBill splitting is a practical programming exercise that introduces financial calculations commonly used in payment systems, budgeting tools, expense trackers, and billing applications.",
"hints": [
"The total amount owed, including the tip, is found by adding the tip percentage on top of the original bill total.",
"Once the full amount including tip is known, splitting it evenly among a group simply means dividing that total by however many people are sharing it.",
"As with any calculation involving money, the final per-person amount should be rounded to exactly two decimal places."
],
"difficulty": 2,
"xp_reward": 110
},
{
"slug": "python-practical-todo-list",
"module": "python-practicals",
"title": "Mini-Project: To-Do List Manager",
"func_name": "process_todo_operations",
"return_type": "list",
"param_types": [
"list"
],
"param_names": [
"operations"
],
"statement": "**State management** through a sequence of operations is a core programming pattern. A to-do list app's underlying logic — add, remove, and mark complete — is a perfect example of maintaining and modifying a collection over time.\n\nIn this challenge, your task is to implement the task-management logic for a to-do list app. Given a list of operations, each formatted as \"add <task>\", \"remove <task>\", or \"complete <task>\", process them in order and return the final list of tasks still remaining, preserving their original addition order.\n\nFor example:\n\n- Operations **[\"add buy milk\", \"add walk dog\", \"complete buy milk\"]** leave only **[\"walk dog\"]** remaining.\n- Operations **[\"add task A\", \"add task B\"]** (no removals) leave **[\"task A\", \"task B\"]**.\n- Operations **[\"add task A\", \"remove task A\", \"remove task A\"]** leave **[]** (second removal has no effect).\n\nYour function should return the list of remaining tasks in their original order.\n\nThis exercise reinforces several important programming concepts:\n\n- **Parsing** structured command strings.\n- **Modifying a list** by appending and removing elements.\n- Handling **idempotent operations** (removing an already-removed item).\n- **Sequential state updates** through a series of operations.\n\nTask list management is used in project management tools, workflow systems, issue trackers, and personal organization applications.",
"original_statement": "Every to-do list app, no matter how polished its interface, is built on the same underlying logic: a running list of tasks that grows when items are added and shrinks when they are removed or marked complete.\n\nWrite the task-management logic for such an app. Given a sequence of operations, each formatted as \"add <task>\", \"remove <task>\", or \"complete <task>\", process them in order and return the final list of tasks still remaining (neither removed nor completed), in the order they were originally added.\n\nFor example, the operations \"add buy milk\", \"add walk dog\", and \"complete buy milk\" leave only \"walk dog\" remaining on the list.",
"hints": [
"Every command in the operation log follows the same basic shape: an action word, followed by the specific task it applies to.",
"Adding a task means appending it to the running task list; both removing a task and marking one complete have the identical effect of taking it out of that list entirely.",
"Attempting to remove or complete a task that was never added, or was already removed, should simply have no effect, rather than causing an error."
],
"difficulty": 4,
"xp_reward": 190
},
{
"slug": "python-practical-word-counter",
"module": "python-practicals",
"title": "Mini-Project: Paragraph Word Counter",
"func_name": "word_counter_top_word",
"return_type": "str",
"param_types": [
"str"
],
"param_names": [
"paragraph"
],
"statement": "**Text analysis** — splitting text into words, cleaning them, and counting frequencies — is a fundamental natural language processing skill. Word frequency analysis is used in search engines, document summarization, and content analysis.\n\nIn this challenge, your task is to build a word frequency counter. Given a paragraph of text, split it into individual words, ignore case differences and attached punctuation, and determine which word appears most frequently. Return that word in lowercase. If there is a tie, return whichever tied word appears first in the paragraph.\n\nFor example:\n\n- The paragraph **\"the quick brown fox jumps over the lazy dog. The dog barks.\"** has the word **\"the\"** appearing 3 times — more than any other word — so **\"the\"** is returned.\n- The paragraph **\"apple apple banana banana\"** has a tie between **\"apple\"** and **\"banana\"** at 2 each, but **\"apple\"** appears first, so it is returned.\n- The paragraph **\"Hello world!\"** returns **\"hello\"** after case normalization and punctuation removal.\n\nYour function should return the most frequent word in lowercase.\n\nThis exercise reinforces several important programming concepts:\n\n- **Splitting** text into tokens.\n- **Cleaning** tokens by removing punctuation and normalizing case.\n- **Counting** frequencies using a dictionary.\n- Finding the **maximum value** in a frequency map.\n\nWord frequency analysis is used in search engines, text classification, sentiment analysis, content recommendation, and information retrieval systems.",
"original_statement": "A word-frequency counter is a clean, classic beginner project for practicing string processing, loops, and dictionaries together — and it is genuinely useful for basic text analysis.\n\nWrite a word counter. Given a paragraph of text, split it into individual words, ignore case differences and any attached punctuation, and determine which word appears most frequently. Return that most frequent word in lowercase. If there is a tie, return whichever of the tied words appears first in the paragraph.\n\nFor example, the paragraph \"the quick brown fox jumps over the lazy dog. The dog barks.\" contains the word \"the\" three times, more than any other word, so \"the\" should be returned.",
"hints": [
"Splitting a paragraph on whitespace produces a list of raw words, but those words may still carry attached punctuation that needs to be stripped away before counting.",
"Comparing words in a case-insensitive way (converting everything to lowercase first) ensures that \"The\" and \"the\" are correctly counted as the same word.",
"A running dictionary mapping each cleaned word to how many times it has appeared so far is the natural way to tally frequencies, and the most frequent entry in that dictionary is the answer."
],
"difficulty": 4,
"xp_reward": 190
}
]