Домашни > Функцията, която казва "Ni!"


Функцията, която казва "Ni!"
Краен срок: 22.10.2024 18:00
Точки: 10

### Контекст Тъй като все още не сте добили достатъчно познания за света на Монти Пайтън, искаме да ви обогатим със следния откъс от техен филм: [![The Knights Who Say "Ni!" - Monty Python and the Holy Grail](/media/resources/homework2.png)](https://www.youtube.com/watch?v=zIV4poUZAQo) ### Въведение Целта на домашното е да напишете функция, която симулира рицарите, които казват "Ni!". Както става ясно от видеото, рицарите винаги отговарят с "Ni!", освен ако не им бъде предоставено "shrubbery" (храсталак) и то само при условие, че храсталакът е "one that looks nice" (такъв, който изглежда хубаво) и "not too expensive" (не прекалено скъп). Е, не винаги, но ние ще го опростим. Целта ви е да напишете функция, която оценява получения си вход и определя дали е получила храсталак, който изглежда хубаво и не е прекалено скъп. ### Задачата Напишете функцията `function_that_says_ni`, която приема произволен брой позиционни и/или именувани параметри. Стойностите на тези параметри могат да бъдат от произволен тип, но тези, които касаят поведението на функцията, са само аргументите от тип `dict` (речник). Всички останали могат да бъдат пренебрегнати. Ако аргумент на функцията (било то позиционен или именуван) е от тип `dict`, то той е потенциално "храст". Речник, който описва "храст", трябва да отговаря на следното условие: **Речникът има ключ от тип `str` със стойност `name`, зад който ключ има стойност от тип `str` и някоя от следните стойности "храст", "shrub", "bush". Може и в комбинация от малки/главни букви.** Речник, който описва "храст", може да съдържа и друг ключ от тип `str` със стойност `cost`, зад който ключ има стойност от тип `int` или `float`, показващ цената на дадения храст, но такъв ключ може и да не се съдържа в речника. Речникът може да има и други ключове, но всичко извън `name` и `cost` не ни интересува. Например: ``` {"name": "чегарак", "cost": 1.00} # Не е "храст", защото "чегарак" не фигурира в списъка по-горе {"name": "храст", "cost": 2.00} # Това е "храст" {"name": "shrub", "cost": 3.00} # Това е "храст" {"name": "bush"} # Това е "храст". Цената не е задължителна. ``` Целта ви е да оцените всички "храст"-и, които вашата функция приеме като вход, и да прецените дали сте удовлетворени, или не. В случай, че не сте получили храсталак (комбинация от "храсти"-и), който изглежда хубаво и не е прекалено скъп, функцията ви трябва да връща `str` със стойност "Ni!". В противен случай трябва да върнете `str`, който съответства на цената на храсталака, който сте получили, във формата "1.23лв" (винаги закръглен до два символа след десетичната запетая и включвайки "лв" накрая. #### Цената (not too expensive) Цената на храсталак се определя като сума от всички "храст"-и, които функцията ви е получила като вход. Един храсталак е прекалено скъп, ако цената му е повече от 42.00лв. #### Хубостта (one that looks nice) Един храсталак изглежда хубав, когато броят от уникалните букви, които са използвани за изписване на имената на всички именувани аргументи на функцията, които представляват "храст"-и, е кратен на целочислената част от цената му. *Кратно се нарича цяло число, което се дели на друго число без остатък. Например: Ако цената на храсталака, който сте получили, е "2.80лв", то той е по-евтин от 42.00лв, но за да удовлетворите функцията, трябва да се уверите и че храсталакът е хубав. Хубав храсталак в този случай би бил само такъв, че броят от уникалните буквите, използвани в имена на именувани аргументи, които представляват "храст"-и, е кратен на 2 (цялата част от 2.80). ``` function_that_says_ni(ab={"name": "храст", "cost": 1.80}, bc={"name": "храст", "cost": 1}) # Броят уникалните букви, използвани за дефиниране на имената на именувани аргументи, е 3 ("a", "b" и "c"). # 3 не е кратно на 2 (цялата част от сумата), така че това не е хубав храсталак. ``` ### Уговорки * "Храст", който има `cost` от тип `float`, може да има стойност най-много до втора цифра след десетичната запетая. Няма да тестваме с по-висока точност. * "Храст", който няма поле с ключ `cost`, се счита за безплатен, т.е. има цена 0. * "Храст", който има поле с ключ `cost`, може да има само стойности `int` и `float` зад този ключ. Няма да тестваме с невалидни цени зад запазеното име за това. * Не очакваме да има такива недоразумения, но за всеки случай - няма да тестваме с вложени храсти. С други думи, не очаквайте аргумент, подаден на функцията, да е колекция, някоя от чиито стойности да е речник, който изпълнява условията за храст. Храст може да бъде само стойност на аргумент, подаден към функцията, но не и речници, които са част от колекция, подадена като аргумент. * Забележете, че при определяне на хубостта се използва целочислената част от общата цена на храсталака (включително цената на тези "храст"-и, които са влезли като позиционни аргументи), но само имената на именуваните аргументи, които са "храст"-и. * В случай, че целочислената част на храсталака е нула, няма как да дефинираме кратност при търсене на хубост, така че приемаме, че храсталакът не е хубав. * Ключовете на речник, които дефинират специална функция са "name" и "cost" и те винаги ще бъдат подавани с малки букви, точно така, както са написани в това изречение. Стойностите, които дефинират храст ("храст", "shrub", "bush"), могат да бъдат подавани и като комбинация от малки/главни букви (например "SHruB"). * Говорейки за имена на именувани аргументи и техния брой "уникални букви", включваме и случаите, в които измежду тези букви има символа "_". Нека този символ се брои за валидна буква. Като изключим този специален символ, всички останали символи ще са малки букви от латиницата, както се препоръчва в PEP8. Не очаквайте комбинации от малки и главни букви там. * **Генерално правило и занапред - очакваме от функциите да върнат резултат, а не да принтират каквото и да било.** ### Пример ``` function_that_says_ni({"name": "храст", "cost": 120}) > "Ni!" # Независимост от всичко останало, очевидно този храсталак е прекалено скъп function_that_says_ni({"name": "храст", "cost": 1}) > "1.00лв" # Цената е под максимума, а общият брой букви, използвани като именувани аргументи за дефиниране на "храст"-и, е 0, което е кратно на 1. function_that_says_ni(aabcc={"name": "bush", "cost": 3.20}) > "3.20лв" # Цената е под максимума. Общият брой уникални букви, използвани като именувани аргументи за дефиниране на "храст"-и, е 3 ("a", "b", "c"). # Целочислената част на цената също е 3. Кратността е изпълнена, т.е. храсталакът е ок и връщаме цената. ```
Дискусия
Илиан Запрянов
18.10.2024 14:11

Примерни тестове за Домашно 2 https://docs.google.com/document/d/1XpVwY-X-NKEvOoYVRD_3qR06xLbnZm8v9ahs0i7L29Y/edit?usp=sharing
Георги Кунчев
16.10.2024 11:42

Тъй като сме написали само букви и "_", няма да тестваме с цифри, но едва ли наличието на цифри би повлияло на имплементацията ти.
Николай Стоянов
16.10.2024 11:22

Здравейте. Имената на именувани аргументи могат ли да съдържат цифри?