1from collections import defaultdict
2
3PRECISION = 4
4
5def курс_в_лева(exchange_rates: dict[str, float]) -> dict[str, float]:
6 return { curr: round(1/rate, PRECISION) for curr, rate in exchange_rates.items() }
7
8def преброй_кинтите(amounts: list[tuple[str, float]]) -> defaultdict[str, float]:
9 # Convert to dictionary to combine/sum the same currencies in one entry
10 by_currency = defaultdict(float)
11
12 for curr, rate in amounts:
13 by_currency[curr] += rate
14
15 return by_currency
16
17def олевчи(curr: str, rate: float, exchange_rates: dict[str, float]) -> float:
18 # Handle BGN case
19 return rate / exchange_rates.get(curr, 1)
20
21def валута_към_левчета(*args: tuple[str, float], **kwargs: float) -> list[tuple[str, float]]:
22 by_currency = преброй_кинтите(list(args))
23
24 return [(c, round(олевчи(c, r, kwargs), PRECISION)) for c, r in by_currency.items()]
25
26def е_патриотична(amount: list[tuple[str, float]], exchange_rates: dict[str, float]) -> str:
27 precision = 2
28 by_currency = преброй_кинтите(amount)
29 total = round(sum(олевчи(c, r, exchange_rates) for c, r in by_currency.items()), precision)
30
31 return "ПАТРИОТИЧНА!" if total == int(total) else "НЕПАТРИОТИЧНА!"
..........
----------------------------------------------------------------------
Ran 10 tests in 0.000s
OK
Виктор Бечев
09.03.2026 11:15Знаеш ли, абсолютно си прав, аз съм в грешка. [Това](https://peps.python.org/pep-0484/#arbitrary-argument-lists-and-default-argument-values) потвърждава казаното от теб.
|
Илиян Гаврилов
06.03.2026 19:16Хмм, реално `**kwargs: float` не е ли вярно, тъй като анотира типа на всеки keyword аргумент? Ако е анотирано `dict[str, float]`, дава warning "`Expected type 'dict[str, float]', got 'dict[str, dict[str, float]]' instead `" при `олевчи(c, r, kwargs)`.
По същата логика, типът на `*args` трябва да е `*args: tuple[tuple[str, float]]`, а не `*args: tuple[str, float]` - тъй като всеки отделен аргумент е `tuple[str, float]`, не целият `args`.
[Source](https://rednafi.com/python/annotate-args-and-kwargs/)
(повреме на писането на този коментар ми се счупи клавиатурата по някаква причина се самоизтриха всички макроси и не можех да пиша 'ч' или '`' и след това получих BSOD на компютъра - обвинявам сайта)
|
| f | 1 | from collections import defaultdict | f | 1 | from collections import defaultdict |
| 2 | 2 | ||||
| n | n | 3 | PRECISION = 4 | ||
| 4 | |||||
| 3 | def курс_в_лева(exchange_rates: dict[str, float]) -> dict: | 5 | def курс_в_лева(exchange_rates: dict[str, float]) -> dict[str, float]: | ||
| 4 | precision = 4 | ||||
| 5 | return { curr: round(1/rate, precision) for curr, rate in exchange_rates.items() } | 6 | return { curr: round(1/rate, PRECISION) for curr, rate in exchange_rates.items() } | ||
| 6 | 7 | ||||
| 7 | def преброй_кинтите(amounts: list[tuple[str, float]]) -> defaultdict[str, float]: | 8 | def преброй_кинтите(amounts: list[tuple[str, float]]) -> defaultdict[str, float]: | ||
| n | 8 | # Convert to dictionary for faster access | n | 9 | # Convert to dictionary to combine/sum the same currencies in one entry |
| 9 | by_currency = defaultdict(float) | 10 | by_currency = defaultdict(float) | ||
| 10 | 11 | ||||
| 11 | for curr, rate in amounts: | 12 | for curr, rate in amounts: | ||
| 12 | by_currency[curr] += rate | 13 | by_currency[curr] += rate | ||
| 13 | 14 | ||||
| 14 | return by_currency | 15 | return by_currency | ||
| 15 | 16 | ||||
| 16 | def олевчи(curr: str, rate: float, exchange_rates: dict[str, float]) -> float: | 17 | def олевчи(curr: str, rate: float, exchange_rates: dict[str, float]) -> float: | ||
| 17 | # Handle BGN case | 18 | # Handle BGN case | ||
| 18 | return rate / exchange_rates.get(curr, 1) | 19 | return rate / exchange_rates.get(curr, 1) | ||
| 19 | 20 | ||||
| 20 | def валута_към_левчета(*args: tuple[str, float], **kwargs: float) -> list[tuple[str, float]]: | 21 | def валута_към_левчета(*args: tuple[str, float], **kwargs: float) -> list[tuple[str, float]]: | ||
| n | 21 | precision = 4 | n | ||
| 22 | by_currency = преброй_кинтите(list(args)) | 22 | by_currency = преброй_кинтите(list(args)) | ||
| 23 | 23 | ||||
| t | 24 | return [(c, round(олевчи(c, r, kwargs), precision)) for c, r in by_currency.items()] | t | 24 | return [(c, round(олевчи(c, r, kwargs), PRECISION)) for c, r in by_currency.items()] |
| 25 | 25 | ||||
| 26 | def е_патриотична(amount: list[tuple[str, float]], exchange_rates: dict[str, float]) -> str: | 26 | def е_патриотична(amount: list[tuple[str, float]], exchange_rates: dict[str, float]) -> str: | ||
| 27 | precision = 2 | 27 | precision = 2 | ||
| 28 | by_currency = преброй_кинтите(amount) | 28 | by_currency = преброй_кинтите(amount) | ||
| 29 | total = round(sum(олевчи(c, r, exchange_rates) for c, r in by_currency.items()), precision) | 29 | total = round(sum(олевчи(c, r, exchange_rates) for c, r in by_currency.items()), precision) | ||
| 30 | 30 | ||||
| 31 | return "ПАТРИОТИЧНА!" if total == int(total) else "НЕПАТРИОТИЧНА!" | 31 | return "ПАТРИОТИЧНА!" if total == int(total) else "НЕПАТРИОТИЧНА!" |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||