Zobrazit plnou verzi příspěvku: Volanie funkcie z programu

michaelflyer
25.04.2008, 07:54
Dobrý deň.
Mám pár otázok na volanie funkcii v lispe. Daný bod a hodnotu mi nechce zobrať do NIRO. Neviete poradiť?
V „NIROZAB“ sa to spracuje a volá program „NIRO“ aby niečo nakreslil. Potom pokračuje a zavolá ho 2x atď....

(defun c:NIROZAB (/)
(zadaj bod St_A)
(zadaj hodnoty St_AV)
(zadaj bod St_Z)
(zadaj hodnoty St_ZV)
.
.
.
.
(zadaj honoty St_? St_?V)
;;;odvolávka na PRVE hodnoty na vykreslenie
(setq v St_A)
(setq v (NIRO))
(setq r St_AV)
(setq r (NIRO))
;;;odvolávka na DRUHE hodnoty na vykreslenie
(setq v St_Z)
(setq v (NIRO))
(setq r St_ZV)
(setq r (NIRO))
;;;odvolávka na ĎALŠIE hodnoty na vykreslenie
(setq v St_?)
(setq v (NIRO))
(setq r St_?V)
(setq r (NIRO))
)

(defun NIRO (/)
;;; tu sa to má vykresliť
)
michaelflyer2008-04-25 08:54:38

Vladimír Michl
25.04.2008, 08:49
Asi by to chtělo vidět skutečný LISP kód (ne pseudokód typu "zadaj bod"). Volání funkcí (ne "programů") z jiných funkcí je jinak naprosto běžný postup, to určitě funguje.

michaelflyer
25.04.2008, 09:00
No, upozorňujem je to dlhé... A ten príklad predtým som zjednodušoval. Je tam viac premenných.
20080425_085757_NIRO_zabradlie.lsp

Vopred ďakujem za rady...

Vladimír Michl
25.04.2008, 10:52
To je opravdu dost dlouhé na nějakou zběžnou analýzu - jen obecně:
 
Pokud funkce nevrací hodnotu, není potřeba ji volat v (setq) - stačí jen (NIRO). Pro omezení problémů s přepsanými hodnotami doporučuji nadefinovat použité symboly jako lokální:
 
(defun NIRO ( / a b c ....)
 
Pro ladění použijte krokování ve VLIDE.

Jan Liska
25.04.2008, 11:06
Jednom doplním:
- ve funkci NIRO máte zbytečně progn (používá se především u if apod.)
- velmi často přepisujete hodnotu proměnné, např:
  (setq r rSt_A)  (setq r (NIRO))
- funkce NIRO navíc nic nevrací
- nepoužíváte lokální proměnné. To sice lze ale problém je v tom, že může dojít k přepsání proměnné jinou funkci - velmi špatně se hledá.

Ferdinand
25.04.2008, 12:48
Prvně by se měla nadefinovat fce NIRO, aby pak následně se dala použít ("zavolat"). Nepoužívat v názvech hodnot či proměnných diakritiku - viz
...
 (command "_clayer" "koty")
  (setq v VšA)  (setq v (NIRO))
...
 

michaelflyer
25.04.2008, 12:52
Pri tom krokovaní tochto príkazu
(r (NIRO))
mi to vyhodilo toto:
_$
3.24617
; error: bad argument type: numberp: nil
_$

Len neviem čo stým ďalej....

A čo sa týka toho (defun NIRO (/ v r a n k1 k2). Tak tomu stále nerozumiem. Mám síce literatúru, kde je to vysvetlené ale pointa mi stále uniká! Som asi lama... Ktoré, písmenka tam môžem dať a ktoré nie.
michaelflyer2008-04-25 12:54:44

Vladimír Michl
25.04.2008, 13:53
"Písmenka" tam dejte taková, jaké lokální proměnné (symboly) v dané funkci používáte - viz popis funkce "(defun)"
 
Příkaz "(r (NIRO))" znamená: vyhodnoť uživatelskou funkci "r" s jedním parametrem, který je určen návratovou hodnotou funkce "NIRO". Existuje taková funkce?

michaelflyer
25.04.2008, 20:14
Popravde, s týmto už nemám žiadne skúsenosti. (defun) teóriu už poznám, len tá praktická časť mi akosi nejde Neviem to využiť. Asi tomu nerozumiem (teda určite!)...

Chcel som dosiahnuť funkciou (r (NIRO)), aby mi hodnotu "r" načítalo do (defun NIRO (/ r v a n)... a tu ďalej s ňou pracovalo.
Čo som čítal, tak ono to berie iba jednu hodnotu. To znamená, keď bod "a" má dve súradnice, tak mi ho nenačíta?

Ďakujem za vašu ochotu mi pomôcť. Takisto aj ostaným ďakujme.

predcis
28.04.2008, 10:18
Pokial som dobre pochopil, unika vam zmysel lokalnych a globalnych premennych a ich vymena medzi funkciami.
Odporucal by som nazyvat premenne podla svojho obsahu, cim sa zvysi prehladnost programov (clovek sa sice trochu viac napise, ale pri ladeni a hladani chyb sa mi to osvedcilo).
Mozno tiez pouzit zapis definicii premennych jednym setq :
t.j. namiesto :
(progn
    (setq x1 (* 18.5 (- 1 (cos (/ ALFA (/ 180 pi))))))
    (setq x2 (cos (/ ALFA (/ 180 pi))))
    (setq x (/ x1 x2))
    (princ x))


pouzit toto - pri prikazoch if sa "usetri" progn:
    (setq
        x1 (* 18.5 (- 1 (cos (/ ALFA (/ 180 pi)))))
        x2 (cos (/ ALFA (/ 180 pi)))
        x (/ x1 x2)
    )
    (princ x)

K tym premennym - je to jednoduche (a trochu ine ako vo VBA ci C). Kazda premenna definovana vo vnutri funkcie je globalna premenna, ktoru vidia vsetky funkcie, pokial tato premenna nebola definovana v hlavicke funkcie ako lokalna premenna.
Priklad :
(defun funkcia1()
     (setq
        Bod1 (getpoint "\Vyber bod 1: ")
        Bod2 (getpoint "\Vyber bod 2: ")
        Mierka 2.0
        Vzd   (vzdialenostBodov Bod1 Bod2)
     )
(testovanie)
)

(defun vzdialenostBodov(b1 b2 / dx dy dz dl)
    (setq
          dx (-
               (nth 0 b2)
               (nth 0 b1)
              )
          dy (-
               (nth 1 b2)
               (nth 1 b1)
              )
          dz (-
               (nth 2 b2)
               (nth 2 b1)
              )
          dl (sqrt
               (+
                  (* dx dx) (* dy dy) (* dz dz)
               )
              )
          Vysledok (* dl Mierka)
    )
(* dl Mierka)
)

(defun testovanie()
(princ Bod1)   ;bude zoznam suradnic
(princ Bod2)   ;bude zoznam suradnic
(princ Mierka) ;bude 2.0
(princ Vzd)    ;bude desatinne cislo
(princ Vysledok)    ;bude rovnake cislo ako Vzd
(princ dx)     ;bude nil
(princ dy)     ;bude nil     
(princ dz)     ;bude nil
(princ dl)     ;bude nil
(princ b1)     ;bude nil
(princ b2)     ;bude nil
)

Takze pokial ste chceli vediet odpoved na otazku :
Chcel som dosiahnuť funkciou (r (NIRO)), aby mi hodnotu "r" načítalo do (defun NIRO (/ r v a n)... a tu ďalej s ňou pracovalo.
Tak odpoved je ta, ze premenna sa odovzda do funkcie takymto zapisom :(NIRO r v a n)

Dufam, ze som vam trochu objasnil situaciu s premennymi a funkciami.