Първо предизвикателство

  1. Разбрахме колко сте тъжни, заради липсата на второ домашно. Това толкова ни трогна, че решихме да не оставим нещата така и ако не с друго, то да ви зарадваме поне с едно малко предизвикателство.

    Срокът е до края на работната седмица. Задачата далеч не е тежка, но очакваме максимално изчистени решения, без излишни повторения, коментари и без нарушение на нито една от конвенциите, описани в PEP 8.

  2. Мисля, че имаме разминаване между тестовете и условието.

    В условието е calculate_coins(0.53) {1: 1, 2: 1, 100: 0, 5: 0, 10: 0, 50: 1, 20: 0}

    А в теста е self.assert_coins(0.15, {10: 1, 5: 1}) Аналогично на условието теста би трябва да бъде

    {1: 0, 2: 0, 5: 1, 10: 1, 20: 0, 50: 0, 100: 0}

    Поправете ме ако греша, но {10: 1, 5: 1} != {1: 0, 2: 0, 5: 1, 10: 1, 20: 0, 50: 0, 100: 0}

  3. Това е просто начина, по който съм избрал да пиша теста. Ако има нули не ги споменавам в речника. Дефинирал съм метод assert_coins, в който {10: 1, 5: 1} се запълва с нули за останалите монети (по default) и тогава се сравнява с резултата от извикването на функцията. Тоест, когато се сравняват стойностите в речника има и нули за липсващите монети.

  4. Във формата за submit се пази последната ти версия. Но няма начин да видиш чужди преди крайния срок, а и вероятно няма да има секция с лични коментари за решенията, а по-скоро това ще се случва на едно общо място(тази тема)

  5. Имам въпрос - каква е разликата м/у предизвикателствата и домашните и ще имаме ли днес 2ро домашно след като имаме предизвикателство? Извинявам се, ако някъде е било отговорено на моя въпрос.

  6. Предизвикателствата са по-простичики домашни, целящи просто да ви накарат да си поиграете с някакъв аспект на езика. От тях ще получавате също точки, което цели да наваксате ако сте пратили слабо домашно, издънили сте се на теста или нещо в този дух.

  7. Сериозно препоръчвам на хората да разгледат решенията. Като цяло моите впечатления:

    1) Среща се неспазване на PEP 8. Най-вече проблеми с whitespace-овете

    2) Срещат се локални променливи от вида i, c, l, ll, suma, integer, Kasa, pet, deset ... са неподходящи по конвенция и/или не успяват да опишат добре за какво ползвате дадено име

    3) Някои решения връщат резултат, който е предварително създаден извън тялото на функцията речник, т.е. при повторно извикване на функцията ще върнат същия обект(в добрия случай правилно конструиран за последното извикване)

    4) Ако смятате да ползвате имена на стандартни функции от Python(sum, any, all, next, ...) за локални променливи или друго, по конвенция се добавя _ като последен символ(пример: sum_)

    5) На места се обхождат индексите на структура вместо самата структура без за това да има (явна) причина. И когато все пак ви се наложи да го правите ползвайте нещо от рода range(len(my_collection)) вместо range(7)

    6) Няма нужда да int()-вате резултат от целочислено деление(//)

    П.П. Горещо препоръчвам да се измисли някаква схема за отбелязване на добри/лоши решения или даже части от тях :)

  8. Да, това е така, когато някой от аргументите е от тип с плаваща запетая. Тогава логично връщания резултат е от същия тип.

    По-добрия вариант(поне според мен) е да се cast-не до int sum_(или каквото там ще използваш) в момента на умножаването. Тъй като монетите са ти зададени в целочислен ми изглежда по-естествено да работим в него директно. А може би дори и да не налагаме изходния тип. По стойност 5 и 5.0 са напълно сравними...

    И все пак Point taken. За 6) имаш право

    Иначе има и други неща, но те са по-индивидуални.

    На едно място видях cast от този вид (int)(...), вероятно идващо от Java. Тук тези скоби не чупят поведението, но имат съвсем друг смисъл. Те са просто приоритет на операциите. Например, ако беше (str if the_answer == 42 else int)(expression). Щеше да подбере съответния тип спрямо 'the_answer' и след това да го използва за кастването.

    И някои решения включват влагане на if statement-и или проверки за гранични случаи(0), когато останалата част от кода им се отнася с тях по напълно очаквания начин :).

    Има и други неща разбира се, но предполагам, че за тях вече хората по-лесно ще се ориентират къде(ако не и защо) може да се направи нещо малко по-добре като разгледат решенията. А ако не им е съвсем ясно дали и къде е това място е добре при желание да разпитат тук например.

  9. Орлине, много добър списък с две леки забалежки. Едната е по точка 6, за която вече се разбрахте. Другата е точка 4.

    Ако говорим за малка функция (4-5 реда) не виждам проблем в това да предефинираме sum, buffer... Важно е човекът, който чете кода след нас да не бъде заблуден, че това име е въпросната вградена функция. Ако говорим за 3-4 реда код, е очевидно къде е дефинирано името sum и е очевидно, че това не е проблем. Но ако не се чувствате много смели, слагайте подчертавката след името.

    Обръщайте внимание на тези неща. Следващото домашно ви е в понеделник и на него ще вземаме точки ако правите глупости.

  10. Хах, да. Специално 4) мислих да изглежда по-скоро като бележка, че може да се получи неприятно в определена ситуация и как да се избегне, когато е нужно :) Но не съм се изразил достатъчно ясно

  11. Здравейте, аз пък искам да попитам нещо относно кастването към инт. За щастие тествах резултатите си с 2.53 лв., което след умножение по 100 връща 252.999996 което след каст към инт става 252, и ест резултатите нататък се объркват. Затова съм ползвал round функцията вместо кастване към инт. Всички, които ползвате кастване към инт, ако пробвате с 2.53 вижте дали има проблем моля :) За да знам аз ли не го правя правилно с round или наистина кастването към инт не е правилно в случая :)

  12. И аз забелязах същия проблем. Видях, че Decimal май оправя проблема. Затова, в кода си имам следното: sum = Decimal(str(sum)) * 100 Decimal ти представя числото, както нормалните хора биха очаквали да се представя - без допълните цифри от един момент нататък.

  13. Аз мога да ти кажа какво точно е фейлнало на повечето хора на решението. http://docs.python.org/2/tutorial/floatingpoint.html

    Ако прочетеш тук какво пише, ще разбереш и сама, но набързо ще ти кажа.

    Пример: ако подадем 2.53 на твоята функция, понеже използваш sum = sum * 100, новата стойност няма да е 253, а ще бъде 252.99999996, което дори ако го кастнеш към int ще стане 252 :) Затова удачна тук е функцията round а не int

Трябва да сте влезли в системата, за да може да отговаряте на теми.