mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-09-24 23:01:18 +08:00
fix(curriculum): improve tests and instructions for Expense Tracker project (#54624)
Co-authored-by: Zaira <33151350+zairahira@users.noreply.github.com>
This commit is contained in:
+31
-31
@@ -63,127 +63,127 @@
|
||||
"title": "Step 13"
|
||||
},
|
||||
{
|
||||
"id": "658238f7604f154ea9a23e1e",
|
||||
"id": "66314f2add0a8b57da5d6d91",
|
||||
"title": "Step 14"
|
||||
},
|
||||
{
|
||||
"id": "65823b0167fd894f4a7ea60a",
|
||||
"id": "658238f7604f154ea9a23e1e",
|
||||
"title": "Step 15"
|
||||
},
|
||||
{
|
||||
"id": "65823bbbdb4eaa4f9d20a0fb",
|
||||
"id": "65823b0167fd894f4a7ea60a",
|
||||
"title": "Step 16"
|
||||
},
|
||||
{
|
||||
"id": "65823cfc74aa564ffc460489",
|
||||
"id": "65823bbbdb4eaa4f9d20a0fb",
|
||||
"title": "Step 17"
|
||||
},
|
||||
{
|
||||
"id": "65823dde36392f505a39f7c7",
|
||||
"id": "65823cfc74aa564ffc460489",
|
||||
"title": "Step 18"
|
||||
},
|
||||
{
|
||||
"id": "65823e87c9741750a22085a7",
|
||||
"id": "65823dde36392f505a39f7c7",
|
||||
"title": "Step 19"
|
||||
},
|
||||
{
|
||||
"id": "65823ff0d4b991510fade1a8",
|
||||
"id": "65823e87c9741750a22085a7",
|
||||
"title": "Step 20"
|
||||
},
|
||||
{
|
||||
"id": "65824111a09164518320088d",
|
||||
"id": "65823ff0d4b991510fade1a8",
|
||||
"title": "Step 21"
|
||||
},
|
||||
{
|
||||
"id": "658244fdf4b0265334711664",
|
||||
"id": "65824111a09164518320088d",
|
||||
"title": "Step 22"
|
||||
},
|
||||
{
|
||||
"id": "65824561f3478e5371a33ae5",
|
||||
"id": "658244fdf4b0265334711664",
|
||||
"title": "Step 23"
|
||||
},
|
||||
{
|
||||
"id": "658246c28575d653d1f89b59",
|
||||
"id": "65824561f3478e5371a33ae5",
|
||||
"title": "Step 24"
|
||||
},
|
||||
{
|
||||
"id": "65824872894f59546e3084e2",
|
||||
"id": "658246c28575d653d1f89b59",
|
||||
"title": "Step 25"
|
||||
},
|
||||
{
|
||||
"id": "65824a1b16631c54fa524154",
|
||||
"id": "65824872894f59546e3084e2",
|
||||
"title": "Step 26"
|
||||
},
|
||||
{
|
||||
"id": "65824c7b4e2da85597693dcf",
|
||||
"id": "65824a1b16631c54fa524154",
|
||||
"title": "Step 27"
|
||||
},
|
||||
{
|
||||
"id": "65824dfdb6815d563b2d3256",
|
||||
"id": "65824c7b4e2da85597693dcf",
|
||||
"title": "Step 28"
|
||||
},
|
||||
{
|
||||
"id": "6582507654b3ed5712341382",
|
||||
"id": "65824dfdb6815d563b2d3256",
|
||||
"title": "Step 29"
|
||||
},
|
||||
{
|
||||
"id": "658252f6b1526d57b103d48a",
|
||||
"id": "6582507654b3ed5712341382",
|
||||
"title": "Step 30"
|
||||
},
|
||||
{
|
||||
"id": "658254db6e12485a48130f57",
|
||||
"id": "658252f6b1526d57b103d48a",
|
||||
"title": "Step 31"
|
||||
},
|
||||
{
|
||||
"id": "658255d5f955175b270f251d",
|
||||
"id": "658254db6e12485a48130f57",
|
||||
"title": "Step 32"
|
||||
},
|
||||
{
|
||||
"id": "6582575b8089f85b8b92d7c8",
|
||||
"id": "658255d5f955175b270f251d",
|
||||
"title": "Step 33"
|
||||
},
|
||||
{
|
||||
"id": "658258c0e5fbe85c14c060cf",
|
||||
"id": "6582575b8089f85b8b92d7c8",
|
||||
"title": "Step 34"
|
||||
},
|
||||
{
|
||||
"id": "65825a9520a0795c8afbef50",
|
||||
"id": "658258c0e5fbe85c14c060cf",
|
||||
"title": "Step 35"
|
||||
},
|
||||
{
|
||||
"id": "65825b758fe85a5cebabc8c5",
|
||||
"id": "65825a9520a0795c8afbef50",
|
||||
"title": "Step 36"
|
||||
},
|
||||
{
|
||||
"id": "65825cda2668995d5168e37c",
|
||||
"id": "65825b758fe85a5cebabc8c5",
|
||||
"title": "Step 37"
|
||||
},
|
||||
{
|
||||
"id": "65825e96b5db5f5dee6bf57c",
|
||||
"id": "65825cda2668995d5168e37c",
|
||||
"title": "Step 38"
|
||||
},
|
||||
{
|
||||
"id": "6582601b2987045e8e7da994",
|
||||
"id": "65825e96b5db5f5dee6bf57c",
|
||||
"title": "Step 39"
|
||||
},
|
||||
{
|
||||
"id": "6582622cb6c11a5f4c5d79b4",
|
||||
"id": "6582601b2987045e8e7da994",
|
||||
"title": "Step 40"
|
||||
},
|
||||
{
|
||||
"id": "6582687859366a618424d84b",
|
||||
"id": "6582622cb6c11a5f4c5d79b4",
|
||||
"title": "Step 41"
|
||||
},
|
||||
{
|
||||
"id": "65826a6e9d189a623141c726",
|
||||
"id": "6582687859366a618424d84b",
|
||||
"title": "Step 42"
|
||||
},
|
||||
{
|
||||
"id": "65826af5b226a5628aa154b1",
|
||||
"id": "65826a6e9d189a623141c726",
|
||||
"title": "Step 43"
|
||||
},
|
||||
{
|
||||
"id": "65826befd75db5632bd73df6",
|
||||
"id": "65826af5b226a5628aa154b1",
|
||||
"title": "Step 44"
|
||||
}
|
||||
],
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658238f7604f154ea9a23e1e
|
||||
title: الخطوة 14
|
||||
challengeType: 20
|
||||
dashedName: step-14
|
||||
dashedName: step-15
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823b0167fd894f4a7ea60a
|
||||
title: الخطوة 15
|
||||
challengeType: 20
|
||||
dashedName: step-15
|
||||
dashedName: step-16
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823bbbdb4eaa4f9d20a0fb
|
||||
title: الخطوة 16
|
||||
challengeType: 20
|
||||
dashedName: step-16
|
||||
dashedName: step-17
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823cfc74aa564ffc460489
|
||||
title: الخطوة 17
|
||||
challengeType: 20
|
||||
dashedName: step-17
|
||||
dashedName: step-18
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823dde36392f505a39f7c7
|
||||
title: الخطوة 18
|
||||
challengeType: 20
|
||||
dashedName: step-18
|
||||
dashedName: step-19
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823e87c9741750a22085a7
|
||||
title: الخطوة 19
|
||||
challengeType: 20
|
||||
dashedName: step-19
|
||||
dashedName: step-20
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823ff0d4b991510fade1a8
|
||||
title: الخطوة 20
|
||||
challengeType: 20
|
||||
dashedName: step-20
|
||||
dashedName: step-21
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824111a09164518320088d
|
||||
title: الخطوة 21
|
||||
challengeType: 20
|
||||
dashedName: step-21
|
||||
dashedName: step-22
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658244fdf4b0265334711664
|
||||
title: الخطوة 22
|
||||
challengeType: 20
|
||||
dashedName: step-22
|
||||
dashedName: step-23
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824561f3478e5371a33ae5
|
||||
title: الخطوة 23
|
||||
challengeType: 20
|
||||
dashedName: step-23
|
||||
dashedName: step-24
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658246c28575d653d1f89b59
|
||||
title: الخطوة 24
|
||||
challengeType: 20
|
||||
dashedName: step-24
|
||||
dashedName: step-25
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824872894f59546e3084e2
|
||||
title: الخطوة 25
|
||||
challengeType: 20
|
||||
dashedName: step-25
|
||||
dashedName: step-26
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824a1b16631c54fa524154
|
||||
title: الخطوة 26
|
||||
challengeType: 20
|
||||
dashedName: step-26
|
||||
dashedName: step-27
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824c7b4e2da85597693dcf
|
||||
title: الخطوة 27
|
||||
challengeType: 20
|
||||
dashedName: step-27
|
||||
dashedName: step-28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824dfdb6815d563b2d3256
|
||||
title: الخطوة 28
|
||||
challengeType: 20
|
||||
dashedName: step-28
|
||||
dashedName: step-29
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582507654b3ed5712341382
|
||||
title: الخطوة 29
|
||||
challengeType: 20
|
||||
dashedName: step-29
|
||||
dashedName: step-30
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658252f6b1526d57b103d48a
|
||||
title: الخطوة 30
|
||||
challengeType: 20
|
||||
dashedName: step-30
|
||||
dashedName: step-31
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658254db6e12485a48130f57
|
||||
title: الخطوة 31
|
||||
challengeType: 20
|
||||
dashedName: step-31
|
||||
dashedName: step-32
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658255d5f955175b270f251d
|
||||
title: الخطوة 32
|
||||
challengeType: 20
|
||||
dashedName: step-32
|
||||
dashedName: step-33
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582575b8089f85b8b92d7c8
|
||||
title: الخطوة 33
|
||||
challengeType: 20
|
||||
dashedName: step-33
|
||||
dashedName: step-34
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658258c0e5fbe85c14c060cf
|
||||
title: الخطوة 34
|
||||
challengeType: 20
|
||||
dashedName: step-34
|
||||
dashedName: step-35
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825a9520a0795c8afbef50
|
||||
title: الخطوة 35
|
||||
challengeType: 20
|
||||
dashedName: step-35
|
||||
dashedName: step-36
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825b758fe85a5cebabc8c5
|
||||
title: الخطوة 36
|
||||
challengeType: 20
|
||||
dashedName: step-36
|
||||
dashedName: step-37
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825cda2668995d5168e37c
|
||||
title: الخطوة 37
|
||||
challengeType: 20
|
||||
dashedName: step-37
|
||||
dashedName: step-38
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825e96b5db5f5dee6bf57c
|
||||
title: الخطوة 38
|
||||
challengeType: 20
|
||||
dashedName: step-38
|
||||
dashedName: step-39
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582601b2987045e8e7da994
|
||||
title: الخطوة 39
|
||||
challengeType: 20
|
||||
dashedName: step-39
|
||||
dashedName: step-40
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582622cb6c11a5f4c5d79b4
|
||||
title: الخطوة 40
|
||||
challengeType: 20
|
||||
dashedName: step-40
|
||||
dashedName: step-41
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582687859366a618424d84b
|
||||
title: الخطوة 41
|
||||
challengeType: 20
|
||||
dashedName: step-41
|
||||
dashedName: step-42
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65826a6e9d189a623141c726
|
||||
title: الخطوة 42
|
||||
challengeType: 20
|
||||
dashedName: step-42
|
||||
dashedName: step-43
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65826af5b226a5628aa154b1
|
||||
title: الخطوة 43
|
||||
challengeType: 20
|
||||
dashedName: step-43
|
||||
dashedName: step-44
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
---
|
||||
id: 65826befd75db5632bd73df6
|
||||
title: الخطوة 44
|
||||
challengeType: 20
|
||||
dashedName: step-44
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You can use the `__name__` variable to determine if a Python script is being run as the main program or if it is being imported as a module (code written in another Python file).
|
||||
|
||||
If the value of `__name__` is set to `'__main__'`, it implies that the current script is the main program, and not a module.
|
||||
|
||||
As a final step, create an `if` statement to check if `__name__ == '__main__'`, and move the `main()` call inside this block.
|
||||
|
||||
With that, the expense tracker project is complete!
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have `if __name__ == '__main__':` in your code.
|
||||
|
||||
```js
|
||||
assert.match(code,/^if\s+__name__\s*==\s*("|')__main__\1\s*:/m);
|
||||
```
|
||||
|
||||
Your `main()` call should be inside the `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /^if\s+__name__\s*==\s*("|')__main__\1\s*:\s*main\s*\(\s*\)/m);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def add_expense(expenses, amount, category):
|
||||
expenses.append({'amount': amount, 'category': category})
|
||||
|
||||
def print_expenses(expenses):
|
||||
for expense in expenses:
|
||||
print(f'Amount: {expense["amount"]}, Category: {expense["category"]}')
|
||||
|
||||
def total_expenses(expenses):
|
||||
return sum(map(lambda expense: expense['amount'], expenses))
|
||||
|
||||
def filter_expenses_by_category(expenses, category):
|
||||
return filter(lambda expense: expense['category'] == category, expenses)
|
||||
|
||||
|
||||
def main():
|
||||
expenses = []
|
||||
while True:
|
||||
print('\nExpense Tracker')
|
||||
print('1. Add an expense')
|
||||
print('2. List all expenses')
|
||||
print('3. Show total expenses')
|
||||
print('4. Filter expenses by category')
|
||||
print('5. Exit')
|
||||
|
||||
choice = input('Enter your choice: ')
|
||||
|
||||
if choice == '1':
|
||||
amount = float(input('Enter amount: '))
|
||||
category = input('Enter category: ')
|
||||
add_expense(expenses, amount, category)
|
||||
|
||||
elif choice == '2':
|
||||
print('\nAll Expenses:')
|
||||
print_expenses(expenses)
|
||||
|
||||
elif choice == '3':
|
||||
print('\nTotal Expenses: ', total_expenses(expenses))
|
||||
|
||||
elif choice == '4':
|
||||
category = input('Enter category to filter: ')
|
||||
print(f'\nExpenses for {category}:')
|
||||
expenses_from_category = filter_expenses_by_category(expenses, category)
|
||||
print_expenses(expenses_from_category)
|
||||
|
||||
elif choice == '5':
|
||||
print('Exiting the program.')
|
||||
break
|
||||
|
||||
--fcc-editable-region--
|
||||
main()
|
||||
--fcc-editable-region--
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def add_expense(expenses, amount, category):
|
||||
expenses.append({'amount': amount, 'category': category})
|
||||
|
||||
def print_expenses(expenses):
|
||||
for expense in expenses:
|
||||
print(f'Amount: {expense["amount"]}, Category: {expense["category"]}')
|
||||
|
||||
def total_expenses(expenses):
|
||||
return sum(map(lambda expense: expense['amount'], expenses))
|
||||
|
||||
def filter_expenses_by_category(expenses, category):
|
||||
return filter(lambda expense: expense['category'] == category, expenses)
|
||||
|
||||
|
||||
def main():
|
||||
expenses = []
|
||||
while True:
|
||||
print('\nExpense Tracker')
|
||||
print('1. Add an expense')
|
||||
print('2. List all expenses')
|
||||
print('3. Show total expenses')
|
||||
print('4. Filter expenses by category')
|
||||
print('5. Exit')
|
||||
|
||||
choice = input('Enter your choice: ')
|
||||
|
||||
if choice == '1':
|
||||
amount = float(input('Enter amount: '))
|
||||
category = input('Enter category: ')
|
||||
add_expense(expenses, amount, category)
|
||||
|
||||
elif choice == '2':
|
||||
print('\nAll Expenses:')
|
||||
print_expenses(expenses)
|
||||
|
||||
elif choice == '3':
|
||||
print('\nTotal Expenses: ', total_expenses(expenses))
|
||||
|
||||
elif choice == '4':
|
||||
category = input('Enter category to filter: ')
|
||||
print(f'\nExpenses for {category}:')
|
||||
expenses_from_category = filter_expenses_by_category(expenses, category)
|
||||
print_expenses(expenses_from_category)
|
||||
|
||||
elif choice == '5':
|
||||
print('Exiting the program.')
|
||||
break
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
```
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: 66314f2add0a8b57da5d6d91
|
||||
title: Step 14
|
||||
challengeType: 20
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You should see something like `<map object at 0xd273a8>` printed on the console, which is the string representation of the map object returned by `map()`.
|
||||
|
||||
To obtain a readable output you need to turn the map object into a list. Do it by passing the `map()` call as the argument to the `list()` function.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should pass the `map()` call as the argument to the `list()` function.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_call("print(list(map(test, [2,3,5,8])))")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def add_expense(expenses, amount, category):
|
||||
expenses.append({'amount': amount, 'category': category})
|
||||
|
||||
def print_expenses(expenses):
|
||||
for expense in expenses:
|
||||
print(f'Amount: {expense["amount"]}, Category: {expense["category"]}')
|
||||
|
||||
def total_expenses(expenses):
|
||||
pass
|
||||
|
||||
--fcc-editable-region--
|
||||
test = lambda x: x * 2
|
||||
print(map(test, [2, 3, 5, 8]))
|
||||
--fcc-editable-region--
|
||||
|
||||
expenses = []
|
||||
```
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658238f7604f154ea9a23e1e
|
||||
title: 第 14 步
|
||||
challengeType: 20
|
||||
dashedName: step-14
|
||||
dashedName: step-15
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823b0167fd894f4a7ea60a
|
||||
title: 步驟15
|
||||
challengeType: 20
|
||||
dashedName: step-15
|
||||
dashedName: step-16
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823bbbdb4eaa4f9d20a0fb
|
||||
title: 步驟 16
|
||||
challengeType: 20
|
||||
dashedName: step-16
|
||||
dashedName: step-17
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823cfc74aa564ffc460489
|
||||
title: Step 17
|
||||
challengeType: 20
|
||||
dashedName: step-17
|
||||
dashedName: step-18
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823dde36392f505a39f7c7
|
||||
title: 步驟 18
|
||||
challengeType: 20
|
||||
dashedName: step-18
|
||||
dashedName: step-19
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823e87c9741750a22085a7
|
||||
title: 步驟 19
|
||||
challengeType: 20
|
||||
dashedName: step-19
|
||||
dashedName: step-20
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823ff0d4b991510fade1a8
|
||||
title: 步驟 20
|
||||
challengeType: 20
|
||||
dashedName: step-20
|
||||
dashedName: step-21
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824111a09164518320088d
|
||||
title: 步驟21
|
||||
challengeType: 20
|
||||
dashedName: step-21
|
||||
dashedName: step-22
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658244fdf4b0265334711664
|
||||
title: 步驟 22
|
||||
challengeType: 20
|
||||
dashedName: step-22
|
||||
dashedName: step-23
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824561f3478e5371a33ae5
|
||||
title: 步驟-23
|
||||
challengeType: 20
|
||||
dashedName: step-23
|
||||
dashedName: step-24
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658246c28575d653d1f89b59
|
||||
title: 步驟 24
|
||||
challengeType: 20
|
||||
dashedName: step-24
|
||||
dashedName: step-25
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824872894f59546e3084e2
|
||||
title: 步驟 25
|
||||
challengeType: 20
|
||||
dashedName: step-25
|
||||
dashedName: step-26
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824a1b16631c54fa524154
|
||||
title: 步驟 26
|
||||
challengeType: 20
|
||||
dashedName: step-26
|
||||
dashedName: step-27
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824c7b4e2da85597693dcf
|
||||
title: 步驟 27
|
||||
challengeType: 20
|
||||
dashedName: step-27
|
||||
dashedName: step-28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824dfdb6815d563b2d3256
|
||||
title: 第 28 步
|
||||
challengeType: 20
|
||||
dashedName: step-28
|
||||
dashedName: step-29
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582507654b3ed5712341382
|
||||
title: 步驟 29
|
||||
challengeType: 20
|
||||
dashedName: step-29
|
||||
dashedName: step-30
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658252f6b1526d57b103d48a
|
||||
title: 第 30 步
|
||||
challengeType: 20
|
||||
dashedName: step-30
|
||||
dashedName: step-31
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658254db6e12485a48130f57
|
||||
title: 步驟 31
|
||||
challengeType: 20
|
||||
dashedName: step-31
|
||||
dashedName: step-32
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658255d5f955175b270f251d
|
||||
title: 步驟 32
|
||||
challengeType: 20
|
||||
dashedName: step-32
|
||||
dashedName: step-33
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582575b8089f85b8b92d7c8
|
||||
title: 步驟 33
|
||||
challengeType: 20
|
||||
dashedName: step-33
|
||||
dashedName: step-34
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658258c0e5fbe85c14c060cf
|
||||
title: 步驟 34
|
||||
challengeType: 20
|
||||
dashedName: step-34
|
||||
dashedName: step-35
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825a9520a0795c8afbef50
|
||||
title: 步驟 35
|
||||
challengeType: 20
|
||||
dashedName: step-35
|
||||
dashedName: step-36
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825b758fe85a5cebabc8c5
|
||||
title: 步驟 36
|
||||
challengeType: 20
|
||||
dashedName: step-36
|
||||
dashedName: step-37
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825cda2668995d5168e37c
|
||||
title: 步驟 37
|
||||
challengeType: 20
|
||||
dashedName: step-37
|
||||
dashedName: step-38
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825e96b5db5f5dee6bf57c
|
||||
title: 步驟 38
|
||||
challengeType: 20
|
||||
dashedName: step-38
|
||||
dashedName: step-39
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582601b2987045e8e7da994
|
||||
title: 步驟 39
|
||||
challengeType: 20
|
||||
dashedName: step-39
|
||||
dashedName: step-40
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582622cb6c11a5f4c5d79b4
|
||||
title: 步驟 40
|
||||
challengeType: 20
|
||||
dashedName: step-40
|
||||
dashedName: step-41
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582687859366a618424d84b
|
||||
title: 步驟 41
|
||||
challengeType: 20
|
||||
dashedName: step-41
|
||||
dashedName: step-42
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65826a6e9d189a623141c726
|
||||
title: 步驟 42
|
||||
challengeType: 20
|
||||
dashedName: step-42
|
||||
dashedName: step-43
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65826af5b226a5628aa154b1
|
||||
title: 第 43 步
|
||||
challengeType: 20
|
||||
dashedName: step-43
|
||||
dashedName: step-44
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
---
|
||||
id: 65826befd75db5632bd73df6
|
||||
title: 步驟 44
|
||||
challengeType: 20
|
||||
dashedName: step-44
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You can use the `__name__` variable to determine if a Python script is being run as the main program or if it is being imported as a module (code written in another Python file).
|
||||
|
||||
If the value of `__name__` is set to `'__main__'`, it implies that the current script is the main program, and not a module.
|
||||
|
||||
As a final step, create an `if` statement to check if `__name__ == '__main__'`, and move the `main()` call inside this block.
|
||||
|
||||
With that, the expense tracker project is complete!
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have `if __name__ == '__main__':` in your code.
|
||||
|
||||
```js
|
||||
assert.match(code,/^if\s+__name__\s*==\s*("|')__main__\1\s*:/m);
|
||||
```
|
||||
|
||||
Your `main()` call should be inside the `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /^if\s+__name__\s*==\s*("|')__main__\1\s*:\s*main\s*\(\s*\)/m);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def add_expense(expenses, amount, category):
|
||||
expenses.append({'amount': amount, 'category': category})
|
||||
|
||||
def print_expenses(expenses):
|
||||
for expense in expenses:
|
||||
print(f'Amount: {expense["amount"]}, Category: {expense["category"]}')
|
||||
|
||||
def total_expenses(expenses):
|
||||
return sum(map(lambda expense: expense['amount'], expenses))
|
||||
|
||||
def filter_expenses_by_category(expenses, category):
|
||||
return filter(lambda expense: expense['category'] == category, expenses)
|
||||
|
||||
|
||||
def main():
|
||||
expenses = []
|
||||
while True:
|
||||
print('\nExpense Tracker')
|
||||
print('1. Add an expense')
|
||||
print('2. List all expenses')
|
||||
print('3. Show total expenses')
|
||||
print('4. Filter expenses by category')
|
||||
print('5. Exit')
|
||||
|
||||
choice = input('Enter your choice: ')
|
||||
|
||||
if choice == '1':
|
||||
amount = float(input('Enter amount: '))
|
||||
category = input('Enter category: ')
|
||||
add_expense(expenses, amount, category)
|
||||
|
||||
elif choice == '2':
|
||||
print('\nAll Expenses:')
|
||||
print_expenses(expenses)
|
||||
|
||||
elif choice == '3':
|
||||
print('\nTotal Expenses: ', total_expenses(expenses))
|
||||
|
||||
elif choice == '4':
|
||||
category = input('Enter category to filter: ')
|
||||
print(f'\nExpenses for {category}:')
|
||||
expenses_from_category = filter_expenses_by_category(expenses, category)
|
||||
print_expenses(expenses_from_category)
|
||||
|
||||
elif choice == '5':
|
||||
print('Exiting the program.')
|
||||
break
|
||||
|
||||
--fcc-editable-region--
|
||||
main()
|
||||
--fcc-editable-region--
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def add_expense(expenses, amount, category):
|
||||
expenses.append({'amount': amount, 'category': category})
|
||||
|
||||
def print_expenses(expenses):
|
||||
for expense in expenses:
|
||||
print(f'Amount: {expense["amount"]}, Category: {expense["category"]}')
|
||||
|
||||
def total_expenses(expenses):
|
||||
return sum(map(lambda expense: expense['amount'], expenses))
|
||||
|
||||
def filter_expenses_by_category(expenses, category):
|
||||
return filter(lambda expense: expense['category'] == category, expenses)
|
||||
|
||||
|
||||
def main():
|
||||
expenses = []
|
||||
while True:
|
||||
print('\nExpense Tracker')
|
||||
print('1. Add an expense')
|
||||
print('2. List all expenses')
|
||||
print('3. Show total expenses')
|
||||
print('4. Filter expenses by category')
|
||||
print('5. Exit')
|
||||
|
||||
choice = input('Enter your choice: ')
|
||||
|
||||
if choice == '1':
|
||||
amount = float(input('Enter amount: '))
|
||||
category = input('Enter category: ')
|
||||
add_expense(expenses, amount, category)
|
||||
|
||||
elif choice == '2':
|
||||
print('\nAll Expenses:')
|
||||
print_expenses(expenses)
|
||||
|
||||
elif choice == '3':
|
||||
print('\nTotal Expenses: ', total_expenses(expenses))
|
||||
|
||||
elif choice == '4':
|
||||
category = input('Enter category to filter: ')
|
||||
print(f'\nExpenses for {category}:')
|
||||
expenses_from_category = filter_expenses_by_category(expenses, category)
|
||||
print_expenses(expenses_from_category)
|
||||
|
||||
elif choice == '5':
|
||||
print('Exiting the program.')
|
||||
break
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
```
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: 66314f2add0a8b57da5d6d91
|
||||
title: Step 14
|
||||
challengeType: 20
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You should see something like `<map object at 0xd273a8>` printed on the console, which is the string representation of the map object returned by `map()`.
|
||||
|
||||
To obtain a readable output you need to turn the map object into a list. Do it by passing the `map()` call as the argument to the `list()` function.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should pass the `map()` call as the argument to the `list()` function.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_call("print(list(map(test, [2,3,5,8])))")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def add_expense(expenses, amount, category):
|
||||
expenses.append({'amount': amount, 'category': category})
|
||||
|
||||
def print_expenses(expenses):
|
||||
for expense in expenses:
|
||||
print(f'Amount: {expense["amount"]}, Category: {expense["category"]}')
|
||||
|
||||
def total_expenses(expenses):
|
||||
pass
|
||||
|
||||
--fcc-editable-region--
|
||||
test = lambda x: x * 2
|
||||
print(map(test, [2, 3, 5, 8]))
|
||||
--fcc-editable-region--
|
||||
|
||||
expenses = []
|
||||
```
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658238f7604f154ea9a23e1e
|
||||
title: 第 14 步
|
||||
challengeType: 20
|
||||
dashedName: step-14
|
||||
dashedName: step-15
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823b0167fd894f4a7ea60a
|
||||
title: 步骤15
|
||||
challengeType: 20
|
||||
dashedName: step-15
|
||||
dashedName: step-16
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823bbbdb4eaa4f9d20a0fb
|
||||
title: 步骤 16
|
||||
challengeType: 20
|
||||
dashedName: step-16
|
||||
dashedName: step-17
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823cfc74aa564ffc460489
|
||||
title: Step 17
|
||||
challengeType: 20
|
||||
dashedName: step-17
|
||||
dashedName: step-18
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823dde36392f505a39f7c7
|
||||
title: 步骤 18
|
||||
challengeType: 20
|
||||
dashedName: step-18
|
||||
dashedName: step-19
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823e87c9741750a22085a7
|
||||
title: 步骤 19
|
||||
challengeType: 20
|
||||
dashedName: step-19
|
||||
dashedName: step-20
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65823ff0d4b991510fade1a8
|
||||
title: 步骤 20
|
||||
challengeType: 20
|
||||
dashedName: step-20
|
||||
dashedName: step-21
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824111a09164518320088d
|
||||
title: 步骤21
|
||||
challengeType: 20
|
||||
dashedName: step-21
|
||||
dashedName: step-22
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658244fdf4b0265334711664
|
||||
title: 步骤 22
|
||||
challengeType: 20
|
||||
dashedName: step-22
|
||||
dashedName: step-23
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824561f3478e5371a33ae5
|
||||
title: 步骤-23
|
||||
challengeType: 20
|
||||
dashedName: step-23
|
||||
dashedName: step-24
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658246c28575d653d1f89b59
|
||||
title: 步骤 24
|
||||
challengeType: 20
|
||||
dashedName: step-24
|
||||
dashedName: step-25
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824872894f59546e3084e2
|
||||
title: 步骤 25
|
||||
challengeType: 20
|
||||
dashedName: step-25
|
||||
dashedName: step-26
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824a1b16631c54fa524154
|
||||
title: 步骤 26
|
||||
challengeType: 20
|
||||
dashedName: step-26
|
||||
dashedName: step-27
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824c7b4e2da85597693dcf
|
||||
title: 步骤 27
|
||||
challengeType: 20
|
||||
dashedName: step-27
|
||||
dashedName: step-28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65824dfdb6815d563b2d3256
|
||||
title: 第 28 步
|
||||
challengeType: 20
|
||||
dashedName: step-28
|
||||
dashedName: step-29
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582507654b3ed5712341382
|
||||
title: 步骤 29
|
||||
challengeType: 20
|
||||
dashedName: step-29
|
||||
dashedName: step-30
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658252f6b1526d57b103d48a
|
||||
title: 第 30 步
|
||||
challengeType: 20
|
||||
dashedName: step-30
|
||||
dashedName: step-31
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658254db6e12485a48130f57
|
||||
title: 步骤 31
|
||||
challengeType: 20
|
||||
dashedName: step-31
|
||||
dashedName: step-32
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658255d5f955175b270f251d
|
||||
title: 步骤 32
|
||||
challengeType: 20
|
||||
dashedName: step-32
|
||||
dashedName: step-33
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582575b8089f85b8b92d7c8
|
||||
title: 步骤 33
|
||||
challengeType: 20
|
||||
dashedName: step-33
|
||||
dashedName: step-34
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 658258c0e5fbe85c14c060cf
|
||||
title: 步骤 34
|
||||
challengeType: 20
|
||||
dashedName: step-34
|
||||
dashedName: step-35
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825a9520a0795c8afbef50
|
||||
title: 步骤 35
|
||||
challengeType: 20
|
||||
dashedName: step-35
|
||||
dashedName: step-36
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825b758fe85a5cebabc8c5
|
||||
title: 步骤 36
|
||||
challengeType: 20
|
||||
dashedName: step-36
|
||||
dashedName: step-37
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825cda2668995d5168e37c
|
||||
title: 步骤 37
|
||||
challengeType: 20
|
||||
dashedName: step-37
|
||||
dashedName: step-38
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65825e96b5db5f5dee6bf57c
|
||||
title: 步骤 38
|
||||
challengeType: 20
|
||||
dashedName: step-38
|
||||
dashedName: step-39
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582601b2987045e8e7da994
|
||||
title: 步骤 39
|
||||
challengeType: 20
|
||||
dashedName: step-39
|
||||
dashedName: step-40
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582622cb6c11a5f4c5d79b4
|
||||
title: 步骤 40
|
||||
challengeType: 20
|
||||
dashedName: step-40
|
||||
dashedName: step-41
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 6582687859366a618424d84b
|
||||
title: 步骤 41
|
||||
challengeType: 20
|
||||
dashedName: step-41
|
||||
dashedName: step-42
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65826a6e9d189a623141c726
|
||||
title: 步骤 42
|
||||
challengeType: 20
|
||||
dashedName: step-42
|
||||
dashedName: step-43
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
id: 65826af5b226a5628aa154b1
|
||||
title: 第 43 步
|
||||
challengeType: 20
|
||||
dashedName: step-43
|
||||
dashedName: step-44
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
---
|
||||
id: 65826befd75db5632bd73df6
|
||||
title: 步骤 44
|
||||
challengeType: 20
|
||||
dashedName: step-44
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You can use the `__name__` variable to determine if a Python script is being run as the main program or if it is being imported as a module (code written in another Python file).
|
||||
|
||||
If the value of `__name__` is set to `'__main__'`, it implies that the current script is the main program, and not a module.
|
||||
|
||||
As a final step, create an `if` statement to check if `__name__ == '__main__'`, and move the `main()` call inside this block.
|
||||
|
||||
With that, the expense tracker project is complete!
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have `if __name__ == '__main__':` in your code.
|
||||
|
||||
```js
|
||||
assert.match(code,/^if\s+__name__\s*==\s*("|')__main__\1\s*:/m);
|
||||
```
|
||||
|
||||
Your `main()` call should be inside the `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /^if\s+__name__\s*==\s*("|')__main__\1\s*:\s*main\s*\(\s*\)/m);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def add_expense(expenses, amount, category):
|
||||
expenses.append({'amount': amount, 'category': category})
|
||||
|
||||
def print_expenses(expenses):
|
||||
for expense in expenses:
|
||||
print(f'Amount: {expense["amount"]}, Category: {expense["category"]}')
|
||||
|
||||
def total_expenses(expenses):
|
||||
return sum(map(lambda expense: expense['amount'], expenses))
|
||||
|
||||
def filter_expenses_by_category(expenses, category):
|
||||
return filter(lambda expense: expense['category'] == category, expenses)
|
||||
|
||||
|
||||
def main():
|
||||
expenses = []
|
||||
while True:
|
||||
print('\nExpense Tracker')
|
||||
print('1. Add an expense')
|
||||
print('2. List all expenses')
|
||||
print('3. Show total expenses')
|
||||
print('4. Filter expenses by category')
|
||||
print('5. Exit')
|
||||
|
||||
choice = input('Enter your choice: ')
|
||||
|
||||
if choice == '1':
|
||||
amount = float(input('Enter amount: '))
|
||||
category = input('Enter category: ')
|
||||
add_expense(expenses, amount, category)
|
||||
|
||||
elif choice == '2':
|
||||
print('\nAll Expenses:')
|
||||
print_expenses(expenses)
|
||||
|
||||
elif choice == '3':
|
||||
print('\nTotal Expenses: ', total_expenses(expenses))
|
||||
|
||||
elif choice == '4':
|
||||
category = input('Enter category to filter: ')
|
||||
print(f'\nExpenses for {category}:')
|
||||
expenses_from_category = filter_expenses_by_category(expenses, category)
|
||||
print_expenses(expenses_from_category)
|
||||
|
||||
elif choice == '5':
|
||||
print('Exiting the program.')
|
||||
break
|
||||
|
||||
--fcc-editable-region--
|
||||
main()
|
||||
--fcc-editable-region--
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def add_expense(expenses, amount, category):
|
||||
expenses.append({'amount': amount, 'category': category})
|
||||
|
||||
def print_expenses(expenses):
|
||||
for expense in expenses:
|
||||
print(f'Amount: {expense["amount"]}, Category: {expense["category"]}')
|
||||
|
||||
def total_expenses(expenses):
|
||||
return sum(map(lambda expense: expense['amount'], expenses))
|
||||
|
||||
def filter_expenses_by_category(expenses, category):
|
||||
return filter(lambda expense: expense['category'] == category, expenses)
|
||||
|
||||
|
||||
def main():
|
||||
expenses = []
|
||||
while True:
|
||||
print('\nExpense Tracker')
|
||||
print('1. Add an expense')
|
||||
print('2. List all expenses')
|
||||
print('3. Show total expenses')
|
||||
print('4. Filter expenses by category')
|
||||
print('5. Exit')
|
||||
|
||||
choice = input('Enter your choice: ')
|
||||
|
||||
if choice == '1':
|
||||
amount = float(input('Enter amount: '))
|
||||
category = input('Enter category: ')
|
||||
add_expense(expenses, amount, category)
|
||||
|
||||
elif choice == '2':
|
||||
print('\nAll Expenses:')
|
||||
print_expenses(expenses)
|
||||
|
||||
elif choice == '3':
|
||||
print('\nTotal Expenses: ', total_expenses(expenses))
|
||||
|
||||
elif choice == '4':
|
||||
category = input('Enter category to filter: ')
|
||||
print(f'\nExpenses for {category}:')
|
||||
expenses_from_category = filter_expenses_by_category(expenses, category)
|
||||
print_expenses(expenses_from_category)
|
||||
|
||||
elif choice == '5':
|
||||
print('Exiting the program.')
|
||||
break
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
```
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: 66314f2add0a8b57da5d6d91
|
||||
title: Step 14
|
||||
challengeType: 20
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You should see something like `<map object at 0xd273a8>` printed on the console, which is the string representation of the map object returned by `map()`.
|
||||
|
||||
To obtain a readable output you need to turn the map object into a list. Do it by passing the `map()` call as the argument to the `list()` function.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should pass the `map()` call as the argument to the `list()` function.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_call("print(list(map(test, [2,3,5,8])))")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def add_expense(expenses, amount, category):
|
||||
expenses.append({'amount': amount, 'category': category})
|
||||
|
||||
def print_expenses(expenses):
|
||||
for expense in expenses:
|
||||
print(f'Amount: {expense["amount"]}, Category: {expense["category"]}')
|
||||
|
||||
def total_expenses(expenses):
|
||||
pass
|
||||
|
||||
--fcc-editable-region--
|
||||
test = lambda x: x * 2
|
||||
print(map(test, [2, 3, 5, 8]))
|
||||
--fcc-editable-region--
|
||||
|
||||
expenses = []
|
||||
```
|
||||
+1
-1
@@ -13,7 +13,7 @@ Start by defining a function named `add_expense` that takes three parameters: `e
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a function named `add_expense`.
|
||||
You should use the `def` keyword to declare a function named `add_expense`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`
|
||||
|
||||
+2
-2
@@ -7,13 +7,13 @@ dashedName: step-2
|
||||
|
||||
# --description--
|
||||
|
||||
A list in Python is a built-in data type that allows you to store many items in a single data structure. In Python, you create a list by putting items inside square brackets `[]`, with each item separated from the following one by a comma.
|
||||
A list in Python is a built-in data type that allows you to store many items in a single data structure. In Python, you create a list by putting items inside square brackets (`[]`), with each item separated from the following one by a comma.
|
||||
|
||||
```py
|
||||
numbers = [1, 2, 3, 4]
|
||||
```
|
||||
|
||||
Create an empty list named `expenses`. You will use it to store each of your expenses.
|
||||
Use a pair of square brackets to create an empty list named `expenses`. You will use it to store each of your expenses.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+11
-3
@@ -7,21 +7,29 @@ dashedName: step-3
|
||||
|
||||
# --description--
|
||||
|
||||
The `expenses` parameter of your `add_expense` function will be a list of expenses. You want to be able to add items at the end of your list. For that you can use the `.append()` list method:
|
||||
The `expenses` parameter of your `add_expense` function will be a list of expenses. You want to be able to add items at the end of your list. For that you'll use the `.append()` list method:
|
||||
|
||||
```py
|
||||
my_list = [2, 4, 7]
|
||||
my_list.append(3)
|
||||
```
|
||||
|
||||
In the example above, after appending `3`, `my_list` would be `[2, 4, 7, 3]`. Replace `pass` with a call to the `.append()` method on the `expenses` list. Don't pass any arguments to `.append()` for now.
|
||||
In the example above, after appending `3`, `my_list` would be `[2, 4, 7, 3]`.
|
||||
|
||||
Replace `pass` with a call to the `.append()` method on the `expenses` list. Don't pass any arguments to `.append()` for now.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have `expenses.append()` in your function.
|
||||
|
||||
```js
|
||||
assert.match(code, /^\s+expenses\.append\s*\(\s*\)/m)
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("add_expense").has_stmt("expenses.append()")`)) })
|
||||
```
|
||||
|
||||
You should not have `pass` in your function.
|
||||
|
||||
```js
|
||||
({ test: () => assert.isFalse(runPython(`_Node(_code).find_function("add_expense").has_pass()`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user