Гергана обнови решението на 29.04.2013 16:23 (преди над 11 години)
+REPOSITORY = 'https://github.com/gmavrova/python-retrospective'
+
+# 1. Константите се задават с главни букви
+# 2. Използване на колекцията dictionary, за намиране на стойности по дадени
+# ключове(в случая месеци), много подходящ вариант за задачата.
+# 3. Tuple(immutable) може да бъде използвано като ключ на dictionary, ако
+# се състои само от стрингове, числа или тюпъли (също imutable елементи).
+# Подходящо, защото може да събере повече от една стойност (съотв. двата
+# месеца и деня) и после да се достъпват тези стойности с индексиране.
+# 4. Подреждането на списъци в речник най-елегантно се осъществява чрез
+# метода dict.setdefault(позволява речника да има mutable стойности),
+# вместо с условен оператор.
+# 5. По-опростеното е винаги по-добре. Препоръчва се една функция/метод да
+# върши само едно нещо.
+# 6. Научих какво е yield функция-генератор и как се създава такава.
+# 7. Вместо comprehension е по-добре да използва функцията starmap(function,
+# iterable), като за iterable взима точно резултата от функцията zip().
+# 8. Функцията zip(*iterables) - връща итератор, чиито елементи са съставени
+# от съчетаване i-тите елементи на итеруемите. Интересно е, че спира
+# когато свършат елементите на по-късото итеруемо.
+# 9. Двойките ключове и стойности в речниците нямат подредба. Ако се изисква
+# да пазим подредени двойки може да пазим списък от тюпъли, но много
+# по-удобен начин е използването на OrderedDict.
+# 10. ОrderedDict.popitem() връща речник и премахва двойка (key, value).
+# Интересното е, че в зависимост от стойността на последната, ако е True
+# връща LIFO подредба, ако False FIFO подредба.
+# 11. Lambda функции - много полезна черта на Python. Moже да се сложи
+# навсякъде, където се очаква дефиниция на функция. Не се налага да се
+# присвоява на променлива, няма return. Редовно се използва в
+# comprehensions, filter(), map(), reduce().
+# 12. Научих какво означава да се предефинира операторът []. Могат да се
+# дефинират класове, чрез __getitem__ и __setitem__, които да отговарят
+# на in оператора, len() функцията, но и да се държат като речници, да
+# връщат стойности по дадени ключове, да се държат като речници.
+# 13. Лесен достъп до елементите на речник dict.keys(), dict.values() and
+# dict.items(). Важно да се има предвид, че тези методи връщат итеруеми,
+# а не списъци.
+# 14. Добър стил на програмиране, при булеви стойности е да се напише if
+# check_result: pass , а не if check_result == Тrue : pass.
+# Също така да се използва is not True вместо != True
+# 15. По-удачна е употребата на функцията filter, вместо list comprehension с
+# условие, или още по-тромавия начин с if-else
+# 16. Добра практика е да се използва in, защото е по-бързо, а и може да се
+# използва с колекции; също така е и оператор.
+# 17. Moдулите трябва да дефинират специфични exception класове, които да
+# наследяват вградени Exception class. Koгато се raise-ва изключение
+# съобщението му се задава като аргумент.
+# 18. Интересно е, че format(format_string, *args, **kwargs) е просто
+# wrapper, който вика vformat(format_string, args, kwargs), която функция
+# извършва реалната работа по форматирането - разбива стринг темплейта на
+# символи и полета за подмяна.
+# 19. За подобни игри препоръчително е използване на константи, вместо
+# подаване на стрингове, за състоанието на играта. Като цяло всичко,
+# което сме сигурни, че няма да се променя е хубаво да се изнася като
+# константа.
+# 20. Важна концепция за аргументите на функциите. Могат да им се задават
+# позиционни параметри чрез аргументи по подразбиране, като вторите
+# трябва да са immutable. Само параметрите, които са в края могат да имат
+# стойности по подразбиране. Ако пък искаме някои параметри да са само
+# keyword, a не позиционни аргументи, тогава ги слагаме след параметър
+# със *.