Вход | Регистрация

Първа задача

  • Условието на първа задача

    Задачата е няколко пъти по-трудна от нулевата. Също така, няколко пъти по-интересна. Убеден съм, че ще имате редица въпроси (или неясноти), така че питайте смело тук.

    14.03.2010
  • Има грешка в условието на unfold. Там пише "skip е опционален четвърти аргумент. Ако е подаден, елементите за които връща истина, се изпускат от списъка:", а в следващите 2 примера са изпуснати елементите за които връща лъжа.

    Освен това имам въпрос за inject. Очаква ли се списъка seq винаги да е непразен? Очевидно, ако се допуска празен списък и init по подразбиране взима първия елемент от seq, е възможно и двете да не съществуват и тогава задачата е недодефинирана.

    14.03.2010
  • Мерси за забележката по условието. Грешката беше в примерите и е поправена. Правилното поведение е: "... Ако е подаден, елементите за които връща истина, се изпускат от списъка"

    Относно inject: Ако едновременно началната стойност init не е подадена и списъка seq е празен - не правете нищо. Няма да тестваме за този случай.

    Всъщност логичното и правилно нещо при невалидни аргументи е да хвърлите изключение (в Python TypeError е предвиден за това). Но за сега не ви караме да го правите, тъй като още не сме говорили за изключения.

    15.03.2010 (променeно 15.03.2010)
  • Е тогава как без изключения да накараме ZeroDivisionError просто да връща False, а да не гърми, защото при all() и при any() си мрънка, че делим на 0?

    15.03.2010
  • Идеята,според мен е да не стигнеш въобще до проблемното число получено чрез деление на 0... Успех :)

    15.03.2010
  • защото при all() и при any() си мрънка, че делим на 0?

    >>> any(x / y for x, y in ((1, 2), (3, 4), (5, 0)))
    True
    15.03.2010
  • all(x / y for x, y in ((1, 2), (3, 4), (5, 0)))

    Traceback (most recent call last):

    File "<pyshell#1>", line 1, in <module>

    all(x / y for x, y in ((1, 2), (3, 4), (5, 0)))

    File "<pyshell#1>", line 1, in <genexpr>

    all(x / y for x, y in ((1, 2), (3, 4), (5, 0)))

    ZeroDivisionError: int division or modulo by zero

    Отделно си мисля, че ако използваме този вход: any(x / y for x, y in ((0, 0), (0, 0), (5, 0))) ще стигнем до делението на нула.

    @Марий Йонов, с Python 3.1.1 съм.

    15.03.2010 (променeно 15.03.2010)
  • Сигурно не си с python3?

    15.03.2010
  • @Владимир -- това е очакваното поведение на all, понеже 1 / 2 и 3 / 4 са истина. Ако напишеш all(x / y for x, y in ((0, 1), (1, 0)))` ще си върне False без да гърми.

    @Кирил -- any знае, че ако намери поне една истина, може да върне True и няма нужда да дооценява. all знае, че ако намери поне една лъжа, може да върне False и няма нужда да дооценява. one знае, че... :)

    15.03.2010
  • Да, но ако се сложи деление на 0 като първи елемент - нещата изгарят. Да разбираме ли, че целта на този пример в задачата е да се докаже, че ако one() намери две истини, изобщо да не си прави труда да продължава, без значение какво има отзад(защото това вече е казано по-нагоре), а не че е нужно да се справя с делението на 0?

    15.03.2010
  • @Кирил -- ама разбира се :)

    15.03.2010
  • В one, когато имаме отрицателни числа това истина ли е?

    15.03.2010
  • Айде сега. Какво е истина и какво не в Python?

    15.03.2010
  • Ами, при мен истина е 1, а всичко останало лъжа... затова и на втрия тест на one - оne([0, 4, 0]) ми изкарва False, а не True. 0->False 4->False 0->False => False. Ползвам Python 3.1. Предполагам, че това няма да е проблем, но все пак... Лошото е, че така няма да мога да си пусна и теста :(

    16.03.2010
  • Поради същите причини ми гърми и последният пример Но, one(x/y for x,y in (1, 1), (3, 3), (5, 0)) ми изписва False

    16.03.2010
  • Обърнете внимание, че в условието не пише "когато е истина", а пише "се оценява на истина".

    Второто се отнася за стойности, за които if влиза в тялото си.

    16.03.2010 (променeно 16.03.2010)
  • Аз не съм бил на тая лекция, ама явно и вие не сте били.

    В Python неистина са False, 0, [], {}, () и None. Като цяло, празните стойности и нулите. Ако искате да проверите дали foo се оценява като истина, това става с bool(foo). По този начин работят и логическите оператори в Python. Но това е имплементационен детайл, който не би трябвало да ви интересува. Няма нужда да пишете if bool(x) , bool(x) and y и прочее, понеже Python го вика така или иначе на всичко.

    Това означава, че ако имате потребителски тип (например си дефинирате вектор), може да го накарата да се оценява като неистина ако предефинирате поведението на bool(). Но за това ще си говорим като говорим за ООП.

    16.03.2010 (променeно 16.03.2010)
  • Мисля, че нещо ми се губи... Когато нещо се оценява като истина, на практика то не е ли истина? Ако в конзолата кажа а=12834 и после оценя а, ми извежда False. Това означава ли, че трябва да си предефинирам bool(a) да връща False само ако а е False, [], (), {}, 0, None?

    16.03.2010 (променeно 16.03.2010)
  • Thumbs_upThumbs_up

    Когато нещо се оценява като истина, на практика то не е ли истина?

    Не винаги. Може bool(x) да е истина, но самото x` да не е идентично с обекта `True. Например:

    >>> x = 42
    >>> bool(x)
    True
    >>> x is True
    False

    Ако в конзолата кажа а=12834 и после оценя а, ми извежда False.

    Добре, да пробваме:

    >>> a = 12834
    >>> bool(a)
    True

    Това означава ли, че трябва да си предефинирам bool(a) да връща False само ако а е False, [], (), {}, 0, None?

    Няма нужда да се предефинира. Вградената функция bool си се държи точно така.

    >>> bool(False)
    False
    >>> bool([])
    False
    >>> bool(())
    False
    >>> bool({})
    False
    >>> bool(0)
    False
    >>> bool(None)
    False
    16.03.2010
  • Един въпрос, който не е точно по конкретната задачата. Ако имаме рекурсивно решение трябва ли да се тревожим, че някой тест може да има прекалено голям вход и да търсим итеративно решение?

    16.03.2010
  • Thumbs_up

    @Елена: Отвори конзолата и пробвай следното

    >>> a = 12834
    >>> if a: print("a is true, obviously")
    ... 
    a is true, obviously
    >>> bool(a)
    True

    Демек, 12834 си се оценява като истина и в момента. Очевидно проблема е някъде другаде (подсказа: в твоя код). Ако публикуваш решението (не във форумите, а тук) ще мога да ти погледна кода и да ти дам друга подсказка. В никакъв случай не го публикувай в тая тема, обаче :)

    @Виктор: Аз бих се тревожил. Нито една от функциите не се решава добре с рекурсия. Въобще, Python е език в който няма tail рекурсия и е далеч по-добре да се ползва итерация където е практично.

    16.03.2010 (променeно 16.03.2010)
  • Относно рекурсията:

    Стефан ми взе първото изречение от устата. За второто бих спорил. Но е факт, че рекурсията не е добро решение в Python.

    А ако някой се чуди защо няма опашкови извиквания в Питон (и защо няма и да има), ето го отговора: http://neopythonic.blogspot.com/...ination.html (Това е блога на пожизнения доброжелателен диктатор на Питон - Гуидо ван Росум)

    16.03.2010 (променeно 16.03.2010)
  • @Йоан: Написах "където е практично".

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

    Но тъй де, моля, спори :)

    16.03.2010
  • @Стефан: "където е практично" е в третото изречение. Аз споря за второто :)

    Ти каза, че нито една от функциите не се решава добре с рекурсия. Споря единствено за това.

    Твърдя, че едната от задачите се решава доста по-елегантно с опашкова рекурсия, отколкото с цикъл. Но тъй като това е Python, а не някой друг език - идеята въобще не е добра.

    Иначе - винаги съм готов за спор, но не е това мястото :)

    16.03.2010 (променeно 16.03.2010)
  • Абе и така не съм навит, освен ако под някоя нямаш предвид unfold и под "опашкова рекурсия" нямаш предвид "опашкова рекурсия и магическо мързеливо cons-ване на списъци". Ама хубаво :)

    16.03.2010