feat(curriculum): add user configuration manager lab (#60845)

Co-authored-by: Dario-DC <105294544+Dario-DC@users.noreply.github.com>
This commit is contained in:
Zaira
2025-08-01 08:05:11 -07:00
committed by GitHub
co-authored by Dario-DC
parent ec51058f81
commit a79319c71f
5 changed files with 487 additions and 4 deletions
+5 -3
View File
@@ -4257,9 +4257,11 @@
"In this workshop, you'll practice working with dictionaries and sets while validating a collection of medical data."
]
},
"lab-placeholder-dictionaries-and-sets": {
"title": "Placeholder - waiting for title",
"intro": [""]
"lab-user-configuration-manager": {
"title": "Build a User Configuration Manager",
"intro": [
"In this lab, you will practice working with dictionaries in Python."
]
},
"review-dictionaries-and-sets": {
"title": "Dictionaries and Sets review",
@@ -0,0 +1,9 @@
---
title: Introduction to the Build a User Configuration Manager
block: lab-user-configuration-manager
superBlock: full-stack-developer
---
## Introduction to the Build a User Configuration Manager
In this lab you will practice dictionaries in Python by building a small app that manages user configuration settings.
@@ -0,0 +1,15 @@
{
"name": "Build a User Configuration Manager",
"isUpcomingChange": true,
"dashedName": "lab-user-configuration-manager",
"superBlock": "full-stack-developer",
"challengeOrder": [
{
"id": "684aaf9ec670c68d20efd0d0",
"title": "Build a User Configuration Manager"
}
],
"blockLayout": "link",
"blockType": "lab",
"helpCategory": "Python"
}
@@ -0,0 +1,457 @@
---
id: 684aaf9ec670c68d20efd0d0
title: Build a User Configuration Manager
challengeType: 27
dashedName: build-a-user-configuration-manager
---
# --description--
In this lab, you will build a User Configuration Manager that allows users to manage their settings such as theme, language, and notifications. You will implement functions to add, update, delete, and view user settings.
**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab.
**User Stories:**
1. You should define a function named `add_setting` with two parameters representing a dictionary of settings and a tuple containing a key-value pair
1. `add_setting` function should:
- Convert the key and value to lowercase.
- If the key setting exists, return `Setting '[key]' already exists! Cannot add a new setting with this name.`
- If the key setting doesn't exist, add the key-value pair to the given dictionary of settings and return `Setting '[key]' added with value '[value]' successfully!`.
- The messages returned should have the key and value in lowercase.
1. You should define a function named `update_setting` with two parameters representing a dictionary of settings and a tuple containing a key-value pair.
1. `update_setting` function should:
- Convert the key and value to lowercase.
- If the key setting exists, update its value in the given dictionary of settings and return: `Setting '[key]' updated to '[value]' successfully!`
- If the key setting doesn't exist, return `Setting '[key]' does not exist! Cannot update a non-existing setting.`
- The messages returned should have the key and value in lowercase.
1. You should define a function named `delete_setting` with two parameters representing a dictionary of settings and a key.
1. `delete_setting` function should:
- Convert the key passed to lowercase.
- If the key setting exists, remove the key-value pair from the given dictionary of settings and return `Setting '[key]' deleted successfully!`
- If the key setting does not exist, return `Setting not found!`
- The messages returned should have the key in lowercase.
1. You should define a function named `view_settings` with one parameter representing a dictionary of settings.
1. `view_settings` function should:
- Return `No settings available.` if the given dictionary of settings is empty.
- If the dictionary contains any settings, return a string displaying the settings. The string should start with `Current User Settings:` followed by the key-value pairs, each on a new line and with the key capitalized. For example, `view_settings({'theme': 'dark', 'notifications': 'enabled', 'volume': 'high'})` should return:
```md
Current User Settings:
Theme: dark
Notifications: enabled
Volume: high
```
1. For testing the code, you should create a dictionary named `test_settings` to store some user configuration preferences.
# --hints--
You should create a dictionary named `test_settings` and add some values to it.
```js
({
test: () => runPython(`
is_dict = isinstance(test_settings, dict)
length = len(test_settings)
assert is_dict and length > 0
`)
})
```
You should define a function named `add_setting`.
```js
({ test: () => assert(runPython(`_Node(_code).has_function("add_setting")`)) })
```
The `add_setting` function should have two parameters.
```js
({
test: () => runPython(`
import inspect
sig = inspect.signature(add_setting)
assert len(sig.parameters) == 2
`)
})
```
`add_setting` should convert the key to lowercase.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light"}
result = add_setting(settings_in_test, ("VOLUME", "high"))
assert "volume" in settings_in_test
assert "VOLUME" not in settings_in_test
`)
})
```
`add_setting` should convert the value to lowercase.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light"}
result = add_setting(settings_in_test, ("volume", "HIGH"))
assert settings_in_test["volume"] == "high"
`)
})
```
`add_setting({'theme': 'light'}, ('THEME': 'dark'))` should return the error message `Setting 'theme' already exists! Cannot add a new setting with this name.`.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light", "language": "English"}
result = add_setting(settings_in_test, ("THEME", "dark"))
expected_msg = "Setting 'theme' already exists! Cannot add a new setting with this name."
assert result == expected_msg
`)
})
```
`add_setting({'theme': 'light'}, ('volume', 'high')` should add a new key-value pair and return the success message `Setting 'volume' added with value 'high' successfully!`.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light"}
result = add_setting(settings_in_test, ("volume", "high"))
expected_msg = "Setting 'volume' added with value 'high' successfully!"
assert result == expected_msg
assert settings_in_test["volume"] == "high"
`)
})
```
`add_setting` should correctly add the given key-value pair to the dictionary.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light"}
result = add_setting(settings_in_test, ("os", "Ubuntu"))
assert "os" in settings_in_test
assert settings_in_test["os"] == "ubuntu"
`)
})
```
You should define a function named `update_setting`.
```js
({
test: () => runPython(`
assert _Node(_code).has_function('update_setting')
`)
})
```
The `update_setting` function should have two parameters.
```js
({
test: () => runPython(`
import inspect
sig = inspect.signature(update_setting)
assert len(sig.parameters) == 2
`)
})
```
The `update_setting` function should convert key to lowercase.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light", "language": "English"}
result = update_setting(settings_in_test, ("THEME", "dark"))
assert "THEME" not in settings_in_test
assert "theme" in settings_in_test
assert settings_in_test["theme"] == "dark"
`)
})
```
The `update_setting` function should convert value to lowercase.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light"}
# Use the existing "theme" key but an uppercase value
result = update_setting(settings_in_test, ("theme", "HIGH"))
assert settings_in_test["theme"] == "high"
`)
})
```
`update_setting({'theme': 'light'}, ('theme', 'dark'))` should update an existing key and return the success message `Setting 'theme' updated to 'dark' successfully!`.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light", "language": "English"}
result = update_setting(settings_in_test, ("theme", "dark"))
expected_msg = "Setting 'theme' updated to 'dark' successfully!"
assert result == expected_msg
assert settings_in_test["theme"] == "dark"
`)
})
```
`update_setting({'theme': 'light'}, ('volume', 'high'))` should return the error message `Setting 'volume' does not exist! Cannot update a non-existing setting.` when the key doesn't exist.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light"}
result = update_setting(settings_in_test, ("volume", "high"))
expected_msg = "Setting 'volume' does not exist! Cannot update a non-existing setting."
assert result == expected_msg
`)
})
```
`update_setting` should correctly update the given key-value pair in the dictionary.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light", "language": "English"}
result = update_setting(settings_in_test, ("language", "spanish"))
assert "language" in settings_in_test
assert settings_in_test["language"] == "spanish"
`)
})
```
You should define a function named `delete_setting`.
```js
({
test: () => runPython(`
assert _Node(_code).has_function('delete_setting')
`)
})
```
The `delete_setting` function should have two parameters.
```js
({
test: () => runPython(`
import inspect
sig = inspect.signature(delete_setting)
assert len(sig.parameters) == 2
`)
})
```
`delete_setting` should convert the key to lowercase.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light", "language": "English"}
result = delete_setting(settings_in_test, "THEME")
assert "theme" not in settings_in_test
assert "THEME" not in settings_in_test
`)
})
```
`delete_setting({'theme': 'light'}, 'theme')` should remove the existing key and return the success message `Setting 'theme' deleted successfully!`.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light", "language": "English"}
result = delete_setting(settings_in_test, "theme")
expected_msg = "Setting 'theme' deleted successfully!"
assert result == expected_msg
assert "theme" not in settings_in_test
`)
})
```
`delete_setting` should return the error message `Setting not found!` when the key doesn't exist.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light"}
result = delete_setting(settings_in_test, "volume")
expected_msg = "Setting not found!"
assert result == expected_msg
`)
})
```
`delete_setting` should correctly remove the given key from the dictionary.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light", "language": "English"}
result = delete_setting(settings_in_test, "language")
assert "language" not in settings_in_test
`)
})
```
You should define a function named `view_settings`.
```js
({
test: () => runPython(`
assert _Node(_code).has_function('view_settings')
`)
})
```
The `view_settings` function should have one parameter.
```js
({
test: () => runPython(`
import inspect
sig = inspect.signature(view_settings)
assert len(sig.parameters) == 1
`)
})
```
`view_settings` should return the message `No settings available.` if the given dictionary is empty.
```js
({
test: () => runPython(`
empty_settings = {}
result = view_settings(empty_settings)
expected_msg = "No settings available."
assert result == expected_msg
`)
})
```
`view_settings` should return formatted settings for non-empty dictionary.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "dark", "notifications": "enabled", "volume": "high"}
result = view_settings(settings_in_test)
assert result.startswith("Current User Settings:")
assert "Theme: dark" in result
assert "Notifications: enabled" in result
assert "Volume: high" in result
`)
})
```
`view_settings` should capitalize the first letter of each setting name.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "dark", "volume": "high"}
result = view_settings(settings_in_test)
assert "Theme:" in result
assert "Volume:" in result
assert "theme:" not in result
assert "volume:" not in result
`)
})
```
`view_settings` should display the correct results and end with a newline character.
```js
({
test: () => runPython(`
settings_in_test = {"theme": "light", "language": "English", "notifications": "enabled"}
result = view_settings(settings_in_test)
assert result == "Current User Settings:\\nTheme: light\\nLanguage: English\\nNotifications: enabled\\n"
`)
})
```
# --seed--
## --seed-contents--
```py
```
# --solutions--
```py
def add_setting(settings, key_value):
key, value = key_value
key = key.lower()
value = value.lower()
if key in settings:
return f"Setting '{key}' already exists! Cannot add a new setting with this name."
else:
settings[key] = value
return f"Setting '{key}' added with value '{value}' successfully!"
def update_setting(settings, key_value):
key, value = key_value
key = key.lower()
value = value.lower()
if key in settings:
settings[key] = value
return f"Setting '{key}' updated to '{value}' successfully!"
else:
return f"Setting '{key}' does not exist! Cannot update a non-existing setting."
def delete_setting(settings, key):
key = key.lower()
if key in settings:
del settings[key]
return f"Setting '{key}' deleted successfully!"
else:
return "Setting not found!"
def view_settings(settings):
if not settings:
return "No settings available."
else:
settings_str = "Current User Settings:\n"
for key, value in settings.items():
settings_str += f"{key.capitalize()}: {value}\n"
return settings_str
test_settings = {
"theme": "light",
"language": "English",
"notifications": "enabled"
}
print(add_setting(test_settings, ("VOLUME", "HIGH")))
print(update_setting(test_settings, ("theme", "dark")))
print(delete_setting(test_settings, "language"))
print(view_settings(test_settings))
```
@@ -1308,7 +1308,7 @@
{ "dashedName": "lecture-working-with-dictionaries-and-sets" },
{ "dashedName": "lecture-working-with-modules" },
{ "dashedName": "workshop-medical-data-validator" },
{ "dashedName": "lab-placeholder-dictionaries-and-sets" },
{ "dashedName": "lab-user-configuration-manager" },
{ "dashedName": "review-dictionaries-and-sets" },
{ "dashedName": "quiz-dictionaries-and-sets" }
]