Трета задача

  1. Не, не е добра идея. :)

    Да щеше да е объркващ, т.к. нямаше да е ясно какво става с нещото, на което го прилагаме.

    Отговора следва от това, че ползваме immutable обекти.

    Публикувано преди
  2. И дори, още по-коварно:

    balance = getBalance()
    print(balance) # -10
    
    absolute = abs(balance)
    print(balance) # 10
    

    Това би било сериозен WTF момент.

    Публикувано преди
  3. Всъщност Кирил наистина не е разбрал правилно въпроса ми и по конкретно: трябва ли обектите от тип Lazy да поддържат операции като например повдигане на степен, комплексно спрегнато и тн., които не са описани в условието на задачата, но все пак се извършват върху обикновените числа?

    Публикувано преди
  4. Ако не е описано в условието на задачата, значи не трябва.

    Публикувано преди
  5. Мкей, ето още малко тестове и от мен - http://paste.debian.net/114590/ ... не че тестват нещо твърде много повече от показаните досега, но отвътре ми идеше да ги групирам по този начин; мисля, че Александър Велин би казал, че това показва някаква лека форма на CDO у мен ;) А, да, и ако някой не разбира защо тестовете в ReflectedTests не минават върху неговото решение - спокойно, няма проблем, всъщност това като че ли всъщност не се изисква от условието на задачата, макар че и някои от предишните пуснати тестове го проверяват...

    А сега и мъничко коментарче върху самото условие: аз ли нещо пропускам, или фразата 'не забравяйте за "десните" и "левите" оператори' всъщност няма много смисъл в случая? :) Нашите класове не се занимават с разпознаване на лексеми и граматически изрази; за това разчитаме на интерпретатора, нали?

    Публикувано преди
  6. Каква е логиката 5 + Lazy(5) да гърми, ако Lazy(5) + 5 минава?

    При твоето решение минават ли reflected? Доколкото разбирам за какво се грижи интерпретатора, то той ще търси дефиниран оператор в int/complex/... и като не го намери ще търси точно reflected в Lazy...

    Публикувано преди
  7. При моето решение има reflected; да, няма логика да няма, особено като се вземе предвид колко лесно се реализират. Това, което исках да кажа, е, че в условието от организаторите на курса няма изискване за reflected ops, така че е напълно възможно решение, което да бъде прието от тях, да не успее да мине всички наши тестове - затова предупреждавам, да не се шашкат хората, ако тяхното се окаже такова :)

    ...и затова в моя test suite ги изведох в отделен клас.

    Публикувано преди
  8. Всъщност, твоите "reflected" са част от условието. Трябва да минават. Зачетете се малко по-внимателно и обърнете внимание на примерите.

    Иначе.

    Когато Python види

    Lazy(5) + 10
    

    Той изпълнява

    Lazy(5).__add__(10)
    

    Аналогично, когато види:

    10 + Lazy(5)
    

    Той изпълнява:

    10.__add__(Lazy(5))
    

    Което, съответно, не работи съвсем. Ключовата дума е __radd__. С търсене в документацията ще се справите сами.

    За справка, __add__ е "левия оператор". __radd__ е "денсия".

    Публикувано преди
  9. Уф. Да, разбира се, в пример в условието го има. Извинявам се за объркването :)

    Публикувано преди
  10. Значи това сте имали предвид под "ляв" и "десен" оператор; аз мислех, че става дума за асоциативността - което действително е работа на интерпретатора. А думата "reflected" я взех направо от http://docs.python.org/py3k/reference/datamodel.html#special-method-names - затова не направих връзката между "десен" и това "r" :)

    Публикувано преди
  11. Ако имаме примерно p = Lazy(10) + Lazy(5), и следкато напишем q = p + Lazy(24), трябва ли да се вика p.force() при създаването на q.

    Публикувано преди
  12. x|

    "Бинарни (двуместни) оператори: +, -, *, /, //, %
    Те се прилагат на двойка "мързеливи" числа или на "мързеливо" и обикновено число. Всички оператори трябва да връщат нова инстанция на мързеливо число. Новото мързеливо число трябва да пази информация за двете числа и оператора, но да НЕ прилага оператора на числата. Целта е "мързеливото" число да изглежда като двоично дърво, чиито поддървета са мързеливи [или обикновено] числа, а във възлите има оператори."

    Публикувано преди
  13. Задължително ли трябва вътрешното представяне на Lazy да е дърво? Може ли да изпозваме, примерно, стринг?

    Публикувано преди
  14. Четете ги тия условия...

    Можете да подходите към задачата по различни начини. Някои идеи, които можете да ползвате са:

    • дърво с оператори във възлите и числа в листата
    • йерархия от наследници на Lazy
    • заигравка с ламбда функции
    • ... и т.н.
    Публикувано преди
  15. Всъщност ако греша, нека ме поправят, но као цяло според мен пуснатите няколко теста тук са достатъчно, за да прецните дали сте го написали както се изисква за пълен брой точки. А на тема кое би било оптималното представяне предполагам може да се водят пространни задълбочени спорове. Тука влиза и разбира се какво смята човек за оптимално дали по-компактно като памет или по-бързо, или по-малко като код... Разни хора :)

    Публикувано преди
  16. Още един тест, за който се сещам е да се направят няколко force-а и да се провери колко пъти се изчислява числото, което някак си не ми се изясни съвсем... Убедени ли сте, че lazy трябва да стане обикновено след като се force-не? Аз нещо не съм...

    Публикувано преди
  17. @Живка: Това, което Виктор казва е, че не трябва да се вика force; q трябва да бъде мързеливо.

    @Светослав: Свободни сте да го имплементирате както искате. Но имплементация с низове ще ти донесат повече проблеми отколкото ползи.

    @Евгени: В конкретния случай бих заложил на четимост и простота на решението :)

    @Станко: Lazy става обикновено число след като се force-не и няма логика force да се вика няколко пъти.

    Публикувано преди
  18. @Йоан: последното изречение трябва да означава, че след като извикаме веднъж метода force(), например:

    five = Lazy(5)
    five.force()

    a) то тогава името five ще сочи към 5
    или
    b) five.force() ще запази изчислената стойност и когато извикаме отново five.force(), ще ни бъде върната запазената стойност?

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

    a = Lazy(10) + Lazy(20)

    a.force()

    или нещо = Lazy(100)
    друго = Lazy(нещо)
    и се опитам да извикам друго.Форсе() Съобщението е : <main.Lazy object at 0x018909B0> Какъв е проблемът според вас : нещо трябва да добавя в конструктора за да прихваща този случай или логиката ми където съхранявам оператор и самите числа като негови деца в бинарно дърво нещо не е много логична :)Помогнете , че релииза наближава :) Поздрави, Никола.

    Публикувано преди
  20. Във втория случай вероятно не правиш проверка дали wrap-ната стойност (това, което се подава като аргумент на конструктура) е просто число (в смисъла на вградения тип) или е Lazy. Първият случай сигурно е свързан с вторият или вътрешната ти имплементация пропуска да извика force някъде.

    Публикувано преди
  21. Малко уточнение какво трябва да връща?

    lazy_number = Lazy(3)

    three = bool(lazy_number)

    print(three)

    Публикувано преди
  22. @Йоан: Отговорът ти повтаря този на Евгений, който ми се струва неясен и затова зададох въпроса отново.

    Ивайло е написал точно това, което имах предвид...

    Публикувано преди
  23. Така-аа, имам два въпроса: 1) Ясно е, че при:

    >>> lazy_number = Lazy(8) + Lazy(42)
    >>> number = lazy_number.force()
    >>> print(number)
    

    ще се изведе: 50 и типът на number е int. Но какво трябва да представлява lazy_number след force() и какво трябва да съхранява? Първи вариант е 50, т.е. пресметнатата стойност. Втори вариант ще бъде: '8 + 42'. Написал съм втория вариант, но ако съм сбъркал и трябва първия - няма проблем. Между другото типа и в двата варианта е Lazy, нали?

    2) Имам малко проблемче с булевите операции (примерно and): Опитах се да предефенирам and(), но при

    >>> boo = Lazy(True) and Lazy(False)
    

    ми дава

    >>> boo
    False
    

    Което донякъде е очевидно, че е False, но аз все пак очаквах да почне да го пресмята чак след като му дам force(), а не веднага.

    Освен това явно въобще не влиза в and, защото сложих един print('Boo!') вътре, ама той въобще не се принтва. Ето го кода на and():

    def __and__(self, other):
        print('Boo!')
        result = bi_op(self, 'and', other)
        return Lazy(result)
    

    функцията bi_op е външна функция (използва се за бинарните операции) и трябва да направи result на "(True) and (False)", ако се дадат self като Lazy(True) и other като Lazy(False).

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

    Така и не можах да разбера откъде идват проблемите със стрингове. Като изключим проблема с булевите операции, всичко останало беше лесно и имаше доста място за по-оптимизирано писане.

    Публикувано преди
  24. @Евгений: Доколкото си спомням дефинирането на and метода се отнася за побитово И (за оператора &).

    Публикувано преди
  25. Мда, и Гугъла от това казва. И с & стана (изписа си 'Boo!'-то). Но няма ли начин да се предефенира и and, or и not?

    Все пак благодаря Ивайло.

    Но по-належащия въпрос е все пак първият, тъй като от това какво точно прави force() зависят поне няколко функции (например >, <, == и другите подобни).

    Публикувано преди
  26. Аз може ли да помоля, ако е възможно да увеличите крайния срок за изпращане на домашното. Благодаря предварително :)

    Публикувано преди

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