Публикувахме условието на четвърта задача. Може да намерите примерния тест в GitHub.
Ако имате въпроси — давайте.
Публикувахме условието на четвърта задача. Може да намерите примерния тест в GitHub.
Ако имате въпроси — давайте.
present()() да гръмне) нали?for_any()(x) и for_all()(x) (за справка вградените функции: any([]) връща False, а all([]) връща True)?present()() трябва да гръмне. Както и ако е някой от другите предикати примерно gt(4)(), lt(0)() и т.н.[] си е аргумент. Гледам че any() и all() връщат грешка. Най-вероятно и нашите така трябва да действат.any и all приемаt iterable затова примера е с празният списък, а нашите функции приемат променлив брой аргументи, които достъпваме през predicates (което винаги е налично и е празният списък, ако подадем 0 на брой аргументи), т.е. има просто синтактична разлика.
аха разбрах какво имаш в предвид. Ами гледайки реализацията на any и all, предполагам, че for_any()(x) трябва да връща False, а for_all()(x) да връща True
Бихте ли показали по някой и друг пример за отрицание и импликация?
От гледна точка на логиката(онази в дебелите книги):
for_any(*predicates) → поне едно от условията в predicates е вярно, т.е. ако няма никакви условия в predicates, то няма нито едно което да е вярно
for_all(*predicates)→ за всички условия в predicates е вярно, т.е. ако няма условия в predicates, няма такова за което да не е вярно, ерго за всичките е вярно...
@Димо: за отрицанието:
>>> (~gt(0))(1)
False
>>> (~gt(0))(0)
True
>>> (~gt(0))(-1)
True
Относно импликацията и на мен ми е интересно за пример. Как става прилагането ѝ?
a(x) >> b(x) или (a >> b)(x)
А очаква ли се отрицанието да работи за:
not_binary = ~(eq(0) | eq(1))
Според мен (eq(0) | eq(1)) би трябвало да ти върне, иначе eq(0) | eq(1) | eq(2) няма да ти работи. Всъщност прилагането на комбинатор в/у предикат(и) трябва да връщат предикат.
Имам един въпрос относно: "Няма значение дали комбинатори ще оценяват предикати, когато това не нужно. Ако a(x) е False, то няма значение дали a(x) & b(x) ще оцени b(x)".
Това трябва ли да означава, че (от примерите в условието) при
digit = oftype(int) & gt(-1) & lt(10)
digit( 1 + 2j ) е ОК да гърми?
digit( 1 + 2j ) би следвало да се счупи още на oftype(int). Идеята на това е че няма значение след като се счупи на oftype, дали ще проверява и gt и lt или веднага ще върне False.
А в комуналния дух на споделяне на тестове, който имаше предния път: http://paste.debian.net/115671/
Не точно. oftype(int) няма да се счупи, а ще върне False, понеже 1 + 2j не е int. И точно това ми беше въпросът - какво е правилното поведение?
Според условието, не е проблем програмата да гръмне( не digit( 1 + 2j ) да върне False, а "изгърми" ) понеже не ни задължават да правим lazy evaluation ( digit( 1 + 2j ) ще се оплаче, че не може да сравни int с complex при gt и/или lt )
От друга страна, ако се направи с "мързеливо оценяване", това ще ни гарантира резултат False, а не грешка (:
Здравейте
не знам дали аз се бъркам обаче докато гледах условието - "oftype(t) -- връща дали аргумена е от тип t (проверява с instanceof)" потърсих нещо за "instanceof" и нищо не намерих :( Да не би да имате предвид isinstance()??
Поздрави, Никола.
П.С. :Д аргумена :Д
@Кирил: Схванах, лошо ползвам 'счупи' като дума, извинявай. :) Щом не държат на lazy оценяване, значи това няма какво друго да направи освен да хвърли, че не може да сравнява int с complex.
В тестовете на Евгени има assert, който много точно описва изискването за for_any - да "връща True, ако поне един от предикатите в predicates връща True за аргумента".
Този тест не минава ако се използва any а не наш си код за обхождане.
Та въпросът ми е в условието стриктна проверка за True ли се има предвид или "истина"?
def test_for_all_extract(self):
def even(n):
if n % 2 == 0:
return True
else:
return 'banichka s boza'
some_predicate = for_all(pred(even), gt(0), lt(10))
self.assertTrue(all(('banichka s boza', True, True))) #OK
self.assertFalse(some_predicate(3)) #Fails
Още малко тестове(не, че тестват нещо по-различно):
@Александър:
Ползва се така: present()(something). Другото е каквото Илиян каза.
Иначе, няма значение какво ще се случи с for_all и for_any когато нямат аргументи. Аз бих го направил консистентно с all и any. Няма да тестваме.
@Димо, @Илиян:
Ако имаме положително число, искаме то да е 42. Приемаме всякакви неположителни числа:
(gt(0) >> eq(42))(number)
@Димо:
~(eq(0) | eq(1)) трябва да работи.
@Кирил:
Point taken за digit. Аз съм го направил с "мързеливо оценяване". Вие го направете както искате -- няма да тестваме за това.
@Никола:
Уупс. Не съм писал на Java от години и все още ме избива на instanceof. Прав си за всичко, което каза -- ще обновя примера.
@Михаил:
Съвършенно прав си. Навсякъде, където съм писал True съм имал предвид "истина". Аналогично с False и "неистина". Обнових условието.
@Евгени:
Ако си оправиш теста, ще ти дам точка.
@Димо:
Повече малки тестове обикновено е по-малко големи. Това има две предимства -- (1) стават по-лесни за разбиране, понеже са по-кратки и (2) дават по-ясна идея коя част от кода ти не работи. В твоя случай, ако test_predicates не мине, не знаеш дали проблема е в lt, present или и двете.
Ако разбиеш твоя на по-дребни (и кохезивни) части, ще ти дам точка.
Теста е оправен.
Готово. Въпреки, че според мен имаше някакъв смел творчески порив там... :D
Как да предефинирам операторът ~? А за операторът >> __rshift__ ли да използвам? И по важно как мога да видя всички оператори, които могат да се предефинират?
Ето малко тестове и от мен: http://pastie.org/1854352
Тестовете които завършват на 2 може и да ви фейлват, тъй като не съм сигурен дали се искат от условието. Те искат операциите да работят и ако някой от операндите е функция, а не задължително дефиниран по "нашия" начин предикат.
@Нели
За операторът ~ виж object.__invert__(self).
За >> операторът предположението ти е вярно :)
Иначе ето един добър старт за това къде можеш да видиш всички оператори: http://docs.python.org/py3k/reference/datamodel.html
Според условието на задачата "За нашите цели, "предикат" е функция на един аргумент, която връща True или False." Това значи ли че решението трябва да работи за изрази от вида pr = gt(13) & lambda x: x < 42 ? Aко да, какъв тогава е смисъла от pred(function) ?
@Иван:
Не, не значи. Ако искаш да комбинираш gt(13) с lambda x: x < 42, то трябва да стане така:
gt(13) & pred(lambda x: x < 42)
Под "функция на един аргумент" визирах математическия термин. Ако искаш по-прецизна дефиниция: обект, с оператор () приемащ един аргумент и връщаш истина или неистина.
@Кирил:
Point taken за digit. Аз съм го направил с "мързеливо оценяване". Вие го направете както искате -- няма да тестваме за това.
Тоест няма проблем да гърми, ако му се подаде string, така ли?
Тъй като в един от тестовете на Евгени (всъщност точно този с digit, от примера в условието на задачата):
def tests_from_task(self):
digit = oftype(int) & gt(-1) & lt(10)
#...
self.assertFalse(digit("a"))
Гърми. Силно. Проблем, или не?
Т.е. ще има ли подобни тестове при вас?
не няма да го тестват това. и аз мислех да питам този въпрос ама по думите на Стефан разбрах, че няма да тестват :)
Абе и аз уж така разбрах, ама викам да double-check-на, та да не осера нещо. :)
Айде, тъй да бъде. :)
Хора, при мен гърми ~:
TypeError: bad operand type for unary ~: 'function'
Например
>>> a = ~(lt(10) & lt(20))
или
>>> t = ~~gt(10)
(Последното е подобно на:
>>> not_positive = ~gt(0)
>>> positive = ~not_positive
)
~(eq(0) | eq(1)) #също не работи.
Друг (всъщност подобен) проблем е с
pr = (lambda x: isinstance(x, int)) >> gt(41)
Грешката е:
TypeError: unsupported operand type(s) for >>: 'function' and 'gt'
Някаква идея как да оправя проклетия проблем?
Забележка: използвам отделни класове за gt, lt и т.н., които наследяват базов клас, където са имплементирани &, |, ~ и другите подобни.
@Евгений: Въпрос на имплементация е.
Предполагам, че знам къде ти е проблема, надявам се никой да не ме нахока за този жокер:
#Bla-bla - some code return not self.whatever_you_want #Maybe with ()
return ~self.whatever_you_wantкоето не върви. Същото важи и за другия ти проблем (помни, че >> за предикатите извършва коренно различна функция от нормалния rshift). Ако проблема ти се корени в нещо друго - кофти тръпка.
Успех. :)
П.С. Аз имам един въпрос, предполага ли се, че комбинаторите for_all и for_any трябва да се държат като предикати?
Предполагам, че не, тъй като иначе щяха да са в графата с предикатите, но все пак да питам (не, че има време, май ще го оставя както съм си го написал).
При мен е
return not self(x)
където x е аргумента, който подаваме най-накрая. Примерно:
>>> a = gt(1)
>>> a(10)
x ще е точно това 10.
Освен това използвам вложена функция във функция за тези предефенирания. return not self(x) е точно във вложената функция.
Иначе аз никъде не използвам ~ и >>, а 'not' и 'нещо if нещо else нещо' (заменя се 'нещо' с каквото трябва - страх ме е да го напиша, за да не ме нахокат, въпреки че времето почти изтече).
Трябва да сте влезли в системата, за да може да отговаряте на теми.