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

Help за curry :)

  • Thumbs_upThumbs_upThumbs_upThumbs_up

    нещо не мога да разбера идеята...може ли някой да ми разясни...

    24.03.2009
  • Thumbs_upThumbs_up

    Присъединявам се :)) Нали тия две звездички, са свързани със речник, а в примерчетата няма такова нещо. Нещо ми е много шантаво. И думи като частичното прилагане ме плашат :)

    25.03.2009 (променeно 25.03.2009)
  • Thumbs_upThumbs_up
    def tuplify(a, b, c): return (a, b, c) # връща n-торка от атрибутите си
    curry(tuplify, 1, c = 3)(2) == (1, 2, 3) # True
    curry(tuplify, 1, c = 3)(b = 2) == (1, 2, 3) # True
    curry(tuplify, 1, c = 3)(2, c = 4) == (1, 2, 4) # True
    curry(tuplify, 1, a = 3) # няма да има извиквания от този вид

    този пример ме притеснява също, може ли да имама повече от един *args - нещо от сорта

    curry(tuplify, 1,3,4 c = 3)(2, c = 4)
    25.03.2009 (променeно 25.03.2009)
  • Thumbs_upThumbs_upThumbs_upThumbs_upThumbs_upThumbs_upThumbs_upThumbs_upThumbs_upThumbs_up

    Забавни снимки.

    редактирано

    този пример ме притеснява също, може ли да имама повече от един *args - нещо от сорта

    curry(tuplify, 1,3,4 c = 3)(2, c = 4)

    По принцип може, но в случая тук се задават две стойности на c, веднъж като позиционен и веднъж като именован аргумент, което е невалидно. Също така curry задава стойности на всички позиционни аргументи, тогава върната функция не би трябвало да приема такива, но пък се прилага с 1 позиционен.

    И по общо...

    Имате функция на няколко аргумента - f(x, y, z). Искате да зададете стойност на един от тях - x, напр. стойността 1, а другите да оставите свободни.

    g = curry(f, 1)

    Получавате g(y, z), такава че за всяко y и за всяко z:

    g(y, z) == f(1, y, z) # е вярно

    Идеята на curry е да фиксирате част от аргументите, а другите да оставите свободни, така получавате функция на по-малък брой – свободните аргументи

    Ако се ограничим до частният случай за функции на два аргумента:

    # фиксира първият аргумент на 2 аргументната функция f
    def curry1(f, x):
        return lambda y: f(x, y)
    
    # за всяко f, x, y имаме:
    f(x, y) == curry1(f, x)(y) # е вярно

    Разбира се тази версия няма да ви даде точки.

    До тук фиксирахме позиционни аргументи. Python позволява и именовани аргументи, и съответно искаме curry да може да фиксира и такива. Вижте test_curry_kwargs в примерния тест.

    Също така това би ви било адски безполезно.

    25.03.2009 (променeно 25.03.2009)
  • А забраната за import е, за да не използваме inspect?

    25.03.2009
  • Например.

    25.03.2009
  • А освен inspect, какви други начини има да определим колко аргумента взима функция, как help() определя с колко аргумента е дадена функция? Питам по принцип, не се отнася за тази задача.

    25.03.2009
  • Thumbs_upThumbs_upThumbs_up

    inspect е съвсем нормален Python модул, който предоставя интерфейс към мета-информацията за живи обекти. Тази информация може да бъде достъпена и без inspect, но просто с чрез него е по-удобно. help използва inspect.

    Иначе най-лесният начин да погледнеш какво има в обект е с dir:

    >>> def afunc(a, b, c, *d, **e):
    ...     return a, b, c, d, e
    ... 
    >>> dir(afunc)
    ['__annotations__', '__call__', '__class__', '__closure__', '__code__',
     '__defaults__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__',
     '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__',
     '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__',
     '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
     '__sizeof__', '__str__', '__subclasshook__']
    >>> dir(afunc.__code__)
    ['__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__',
     '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__',
     '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
     '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars',
     'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags',
     'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names',
     'co_nlocals', 'co_stacksize', 'co_varnames']
    >>> afunc.__code__.co_name
    'afunc'
    >>> afunc.__code__.co_names
    ()
    >>> afunc.__code__.co_nlocals
    5
    >>> afunc.__code__.co_varnames
    ('a', 'b', 'c', 'd', 'e')
    25.03.2009 (променeно 25.03.2009)
  • >>> afunc.__code__.co_varnames ('a', 'b', 'c', 'd', 'e')

    Това е идеално, но не за всички функции. Например: map.__code__.co_varnames е невалидно...

    Т.е. ако в някой от тестовете се подаде map на curry, ще загубим точки...

    Освен това, ако приемем, че имаме функция от вида: def tuplify(a, b, c): d = 2 return (a, b, c, d)

    tuplify.__code__.co_varnames връща ('a', 'b', 'c', 'd'), което е невалидно в контекста на условието. Т.е. ако подадете такава "специална" функция, отново нашата ще "гръмне".

    Така че според мен въпросът остава отворен. За тези, които са предали задачите и са използвали този подход - моля опитайте да подадете map (или filter) и някаква "специална" функция като аргумент. Надявам се аз да съм се объркал нещо (ако е така sorry за спама).

    29.03.2009 (променeно 29.03.2009)
  • В случая с curry инспекция не ти е необходима. Иначе може да погледнеш кода на модула inspect.

    29.03.2009
  • Т.е. задачата ще се проверява за именованите параметри само с функции, които имат __code__. Супер :) Благодаря за отговора.

    29.03.2009
  • Според мен Димитър имаше предвид да помислиш друго решение.

    29.03.2009
  • Опааа... мда... благодаря за бързата намеса :)

    29.03.2009

  • http://google.bg

    30.03.2009 (променeно 30.03.2009)