Hledáme programátora SQL, PHP/Nette, Javascript. Práce z domova možná
Zobrazují se odpovědi 1 až 12 z 12

Ruby -quot; nil can't be coerced into Fixnum " Error

  1. jamesm Hodnocení: 1 (100%) jamesm je zatím velká neznámá
    1
    Momentálne pracujem na jednom algoritmickom probléme v Ruby, využívajúc pritom memoizáciu.
    Využívam pritom vlastnú funkciu, a tu je kameň úrazu, pretože za určitých okolností mi neviem preťo vráti nil a potom už neprebehne jednoduché sčítanie čísel (ak som to správne vydedukoval z nasledujúcej chyby) :
    Kód:
    `+': nil can't be coerced into Fixnum (TypeError) na riadku 6
    Tu je môj kód:
    Kód:
    $p = Hash.new
    
    def Vyber(n)
      return 0 if n==0 
      if !($p.has_key?(n))
        r = Vyber(n/2) + Vyber(n/3) + Vyber(n/4)
        r = n if n > r 
        $p[n] = r
      else
        r = $p.key(n)
      end  
      return r  
    end
    
    while n = $stdin.gets
      n = n.chomp.to_i
      print Vyber(n).to_s + "\n"
    end
    Online spustiteľné prostredie: https://ideone.com/uYmam

    Existuje nejaký postup, ako to ošetriť, resp. robí funkcia niečo s premennými, čo by nemala?

  2. Co se právě děje na Webtrhu?
  3. Chybná logika:
    Kód:
    r = $p.key(n)
    Vrací nil, pokud nenajde příslušný klíč

    Správně =>
    Kód:
    r = $p[n]

  4. naniccz Hodnocení: 2 (100%) naniccz je na dobré cestě
    3
    Martin Schlemmer:
    O Ruby nic nevim, ale podle me podminka
    Kód:
    if !($p.has_key?(n))
    zajisti prave ze se r = $p.key(n) vola pouze pokud klic existuje.

  5. Nemluvím o podmínce
    Kód:
    if !($p.has_key?(n))
    ale o přiřazení v druhé větvi podmínky
    Kód:
    r = $p.key(n)
    To má být
    Kód:
    r = $p[n]
    ( + Jak by tady pomohly lepší názvy proměnných.)

  6. naniccz Hodnocení: 2 (100%) naniccz je na dobré cestě
    5
    M.S.: No to ja o tom mluvim taky
    Kód:
    if !($p.has_key?(n)) -- pokud v p neni klic n
        ... nejaky kod ...
      else -- else, tedy v p je klic n
        r = $p.key(n) -- tedy nikoli nil
      end
    a taky jsem neprisel, proc by se ten program nemel zacyklit, ale treba je to ucel :-)

    ---------- Post added 27.6.2011 at 21:15 ----------

    Jsem uplne mimo, opravdu po tom prepsani na $p[n] to dobehne, a dokonce se to nezacykli. To je vlivem nejakeho zaokrouhlovani? Ve Schemu to nedobehne.

  7. Ten řádek dělá něco jiného, než si myslíte.
    hsh.key(value) -> key
    Returns the key for a given value. If not found, returns nil.
    Vy ale chcete value, ne key.

    Analogie v PHP by vypadala takto

    Chyba:
    Kód:
    if( ! empty($cache[$key]) ) {
        $result = array_search($key, $cache);
    }
    Správně:
    Kód:
    if( ! empty($cache[$key]) ) {
        $result = $cache[$key];
    }

  8. naniccz Hodnocení: 2 (100%) naniccz je na dobré cestě
    7
    Aha, moje chyba, vycházel jsem z vašeho tvrzení Vrací nil, pokud nenajde příslušný klíč (místo klíč tedy spíš hodnotu), tak autorův problém je vyřešen. A teď ještě by mě zajímalo, jaktože se to nezacyklí, když pro jiné než nulové číslo to volá samo sebe na poloviční číslo --> tedy se neustále limitně blíží k nule... Předpokládám že to je tedy demonstrace zaokrouhlovací nepřesnosti, resp. nematematičnosti Ruby?

    ---------- Post added 27.6.2011 at 21:23 ----------

    Nebo ještě varianta, že to jsou pouze celá čísla, a pak to je triviální :-)

  9. Vrací nil, pokud nenajde příslušný klíč (místo klíč tedy spíš hodnotu)
    Opravdu vrací klíč k příslušné hodnotě, pokud existuje. Ale vy chcete rovnou tu hodnotu. :)

    Výsledkem dělení integeru je v Ruby zase integer, proto se to nezacyklí.
    Určitě by bylo čistější v té rekurzivní funkci stanovit jednoznačný base case, tohle spoléhá na vlastnost konkrétního jazyka.

  10. naniccz Hodnocení: 2 (100%) naniccz je na dobré cestě
    9
    Nojo, teď už je mi to jasné. Celý zmatek vznikl na tom, že Vrací nil, pokud nenajde příslušný klíč vy chápete jako hledá klíč, který odpovídá hodnotě argumentu (a vrací jej), zatímco já jako že pouze hledá klíč uvedený v argumentu (a vrací hodnotu). Díky za lekci Ruby, a poučení pro příště je, neplést se do diskuse o jazyku, který jsem nikdy neviděl :-)

  11. Nepřesně jsem se vyjádřil a za způsobené nedorozumění se omlouvám.
    Pro zajímavost jak ten kód vypadá ve Scheme?

  12. naniccz Hodnocení: 2 (100%) naniccz je na dobré cestě
    11
    Zrovna jsem to zavřel, grr, naštěstí to je na půl minutky:
    Kód:
    (define (vyber n)
      (if (eq? n 0) 0
          (let ((r (+ (vyber (floor (/ n 2))) (vyber (floor (/ n 3))) (vyber (floor (/ n 4))))))
            (if (> n r) n r))))
    vypadá takhle (se zaokrouhlováním), aby to vracelo stejné výsledky (jinak by tam nebylo volání floor, a argument by se neustále čtvrtil, půlil a dortíkoval, a sežral celou RAM)

  13. jamesm Hodnocení: 1 (100%) jamesm je zatím velká neznámá
    12
    Ďakujem Martinovi za veľmi dobré objasnenie problému. Keďže v Ruby iba začínam programovať, mal by som si prečítať dôkladnejšie dokumentáciu ;)

Hostujeme u Server powered by TELE3