Biologie | Chimie | Didactica | Fizica | Geografie | Informatica | |
Istorie | Literatura | Matematica | Psihologie |
Locul limbajului LISP
Autorii AutoCAD-ului au gasit cu cale sa asocieze acest limbaj cu sistemul de proiectare asistata propus de ei, deoarece au analizat multimea de limbaje si au constatat ca se potriveste cel mai bine necesitatilor unui astfel de sistem. Ceea ce se doreste de la limbaj intrun astfel de caz este sa permita crearea si manipularea omogena a unor entitati eterogene. Dorim sa tratam unitar atat numere, cat si siruride caractere, entitati geometrice sau multimi formate cu acestea. Usor ajungi la concluzia ca toate pot fi cuprinse in LISTE, asupra carora doresti sa faci diverse PRELUCRARI (deci LIST PROCESSING . ).
Daca adaugam la asta usurinta de implementare a limbajului LISP,recunoscuta de toata lumea, constati ca, intr-adevar, este un limbaj potrivit pentru proiectarea asistata.
Dezavantajul major este ca e un limbaj putin cunoscutde publicul larg. Se cunoaste, eventual, BASIC, FORTRAN, PASCAL, COBOL, chiar si C, dar LISP mai putin. Abia versiunea 11 a AutoCAD-ului asociaza limbajul C (pe langa AutoLISP) cu sistemul de proiectare asistata.
Ce inseamna "interpretor"?
Spunem ca ansamblul actiunilor exprimate prin cuvinte din vocabularul limbajului, asupra carora se aplica regulile gramaticale proprii, se numeste "program". Un program este deci o insiruire de linii de text.
Ce este o linie de program?
O linie de program este un sir de cuvinte separate prin spatii (blancurii) si incheiate cu un semn special (invizibil), numit "terminator de linie". Practic, linia se incheie apasand tasta "Enter". Efectul vizibil este ca s-a trecut la linia urmatoare. Daca acceptam denumirile consacrate pentru acest terminator, ca "ENTER", sau "RETURN", sau "CARRIAGE RETURN" (adica "intoarcerea carului" de tiparire ) si-l notam <CR> , atunci liniile de program pot arata astfel:
Xxx xx xxxxx x xxxx<CR>
Xxxxx x xxx xxxx xxxxxx<CR>
In multe limbaje (PASCAL, C, LISP) nu mai conteaza unde se termina o linie. Sigur ca liniile trebuie sa se incheie la sfirsituri de cuvinte, adica separatorul "blanc" poate fi oricand inlocuit cu <CR>. Programatorul hotaraste unde s-o faca, legat numai de instinctele de lizibilitate ("citibilitate") ale programului. De retinut ca nu conteaza daca se scrie cu litera mare sau mica (cu mici exceptii).
Programele astfel scrise trebuie apoi traduse in limba masinii. Traducerea poate fi facuta printr-un "compilator" sau un "interpretor". Compilatorul traduce intregul program, ca ansamblu, intr-un ansamblu de coduri pe care le intelege calculatorul. Interpretorul traduce liniile pe rand, pe masura ce i se fac cunoscute.
In mod tipic limbaje ca PASCAL, FORTRAN, C sunt implementate prin compilatoare, iar BASIC prin interpretor. Ei bine ,AutoLISP este inplementat printr-un interpretor.
Asta ne permite sa introducem programul de la tastatura, linie cu linie, observand direct efectele si eventualele erori.
Daca totusi, programul este scris separat, acesta poate fi "incarcat" in AutoCAD ca ansamblu (folosind functia "load"), dar tratamentul va fi acelasi: citind liniile succesiv, nterpretorul isi intrerupe activitatea atunci cind intilneste o eroare, dand evident informatii despre aceasta ("mesaj de eroare"). Un compilator care ar face acelasI lucru, ar continua sa traduca si celelale linii, informand asupra erorilor abia in final, cu referire la fiecarelinie eronata. Si, ca sa extindem explicatia, dupa ce a trecut o dara prin program, sesizand erorile locale, compilarorul trece a doua oara, sesizand erorile globale. Mai exact, in prima faza compilatorul observa care cuvinte sau "fraze" sunt rau scrise iar in faza a doua stabileste daca trimiterile dintr-o parte in alta a programului sunt corecte. Astfel de trimiteri se fac pe baza unor instructiuni de genul "go to" catre locatii marcate prin etichete (labels). Un interpretor nu are o a doua faza,ba AutoLISP nici nu foloseste trimiteri si etichete, ca sa fie clar. In AutoLISP nu exista instructiuni GO TO, totul curge simplu, de sus in jos .
Filosofia limbajului AutoLISP
LISP inseamna procesare de lista. Olista este un sir de "cuvinte" separate prin spatii (sau <CR>-uri) si incluse intre paranteze rotunde.
O lista poate arata astfel:
(xx xxx x xxxx)
sau
(xx xxx
x xxxx)
Fiecare cuvant poate fi la randul lui o lista; includerea listelor una in alta se numeste "imbricare". Nivelul (sau adancimea) de imbricare nu este limitat(a) decat de memoria calculatorului. Iata un exemplu de lista "pe bune":
Este o lista formata din trei articole (sau atomi): un asterisc, numarul intreg 23 si numarul real 3.2. Primul articol exprima un nume de functie -functia inmultire, iar urmatoarele doua, argumentele acesteia. Actiunea intreprinsa de catre AutoLISP asupra listei este evaluarea ei. Practic, inima AutoLISP-ului este evaluatorul. Ca efect al evaluarii listei, se returneaza valoarea ei.
In cazul prezentat, evaluarea conduce la inmultirea lui 23 cu 3.2 si returnarea rezultatului 73.6. Este exact ca si cand in loc de (* 23 3.2) am scrie (73.6). Daca evaluarea nu conduce la o marime semnificativa, pentru simetria limbajului ceva tot trebuie sa se returneze: se returneaza nil, care inseamna "nimic". De exemplu o functie AutoLISPeste textscr care comuta ecranul din mod grafic in mod text. Daca intr-o linie AutoLISP punem (textscr), atunci are loc comutarea cu pricina,iar evaluarea "listei" returneaza nil.
O lista poate fi imbricata, cum spuneam, in alta lista. Mai intai este evaluata lista cea mai adanc imbricata. Rezultatul returnat este pus in locul ei, urmand eevaluarea listei exterioare, care va considera acest rezultat ca element de lista. Iata un exemplu:
Se evalueaza mai intai lista interioara, obtinandu-se 73.6 si rezultand
Acum se evalueaza aceasta lista care adunarea lui 11 cu 73.6 si 10. Se retutneaza 94.6, evident. Explicam unor studenti sa-si imagineze acest proces ca pe cel ce se produce punand intr-o tigaie o felie de paine cu o bucata de unt deasupra: cand tigaia este pusa pe foc, mai intai se topeste untul (adica paranteza cea mai interioara), si apoi se prajeste felia de paine (paranteza exterioara), care a incorporat untul topit in ea. Sigur ca ei mi-au spus ca vor sa faca aceasta experienta dar nu dispun decat de felia de paine . L-am replicat ca daca se ocupa intens de AutoCAD/ AutoLISP vor face repede rost de tot materialul didactic. Cu timpul, ochiul se obijnuieste cu aceste constructii (in care parantezele joaca un rol determinant) si recunoaste global actiunile cuprinse intr-un program.
Cum procedam?
Ne aflam in AutoCAD. In zona de dialog se afla binecunoscutul prompter:
Command:
Daca acum, in loc de a da o comanda AutoCAD (cum ar fi LINE), punem o paranteza deschisa, deja am invocat interpretorul de AutoLISP. O sa ziceti ca nu se poate sa se intample asa ceva, deoarece nu am incheiat linia. Totusi asa se intampla, si iata de ce: daca puneti:
Command:(* 23 3.2)
Se observa ca dupa * exista un spatiu. In AutoCAD orice spatiu incheie linia, ca si cand ar fi fost apasat Enter, nu-i asa ? Ei bine, uitati-va ca am putut sa continui linia, scriind23, etc. Asta ne determina sa acceptam ca nu AutoCAD a preluat informatiile din linie, ci altcineva. Acest "altcineva" este chiar interpretorul de AutoLISP. Efectul evaluarii acestei linii apare dupa ce apasam Enter in urma parantezei inchise; pe linia urmatoare apare:
adica rezultatul evaluarii listei. Daca nu puneam paranteza inchisa si apasam Enter, atunci pe linia urmatoare apare:
1>
Asta vrea sa spuna: vezi ca ai o paranteza deschisa pe care nu ai inchis-o; nu-i nimic, poti sa scrii alte linii in continuare, dar ai grija sa inchizi paranteza.
Iata cum ar putea sa decurga introducerea de linii:
Command: (+ 11
1> (* 23
2> 3.2)
1> 10)
Command:
Se vede ca suntem informati permanent asupra numarului de paranteze ramase neinchise. In final primim rezultatul evaluarii listei externe.
Cred ca e clar. Avem libertatea de a introduce linii de program AutoLISP direct din AutoCAD pe prompterul "Command:". Cand am inchis si ultima paranteza - perechea primei paranteze deschise - ansamblul "programului"este interpretat prin evaluarea dinspre interior a fiecarei paranteze, returnandu-se rezultatul. Daca s-a strecurat o eroare, evaluarea nu mai continua, transmitandu-se un mesaj de eroare.
Iata un exemplu cu eroare:
Command: (+ 11
1> (blabla 23
2> 3.2)
1> 10
error: null functtion
(BLABLA 23 3.2)
(+ 11 (BLABLA 23 3.2) 10)
Command:
Se observa ca am introdus in loc de functia " * " o functie caraghioasa, numita de mine " blabla"; totusi, pana ce nu incheiem imperecherea parantezelor, AutoLISP nu se "sifoneaza". El ne informeaza constincios asupra numarului de paranteze neanchise (prin "1>" , "2>"). Abia cand am imperecheat si ultima paranteza, evalueaza totul si constata ca nu cunoaste functia "blabla". Mesajul pe care il transmite are intotdeauna forma:
error: mesaj
unde mesaj este un text corelat cu eroarea sesizata de AutoLISP. Ansamblul acestor mesaje si cauzele lor se prezinta in anexa C. Este foarte util sa aveti in fata aceste informatii cand purcedeti sa lucrati in AutoLISP. In cazul nostru, primim mesajul "null function", adica functia nula. Sigur ca am putea oricand sa definim (vom vedea cum) o functie cu numele "blabla", de ce nu? In acest caz functia respectiva s-er executa si n-am mai primi acest mesaj de eroare.
Dar sa vedem mai departe. Observata ca pe linia urmatoare AutoLISP pune lista in care s-a gasit eroarea. Remarcati faptul ca numele functiei este scris cu litere mari. Asta ne lamureste ca AutoLISP transforma mai intai toate numele de functii (dar si alte nume) in litere majuscule si abia dupa aceea le interpreteaza. Este logic sa se intample asa; ganditi-va in cate feluri am putea scrie numai acest cuvant (Blabla, BlaBla, BLAbla, etc.) si cat timp ar lua compararea fiecarei variante cu numele simbolice aflate in baza de date a AutoLISP-ului. In continuare este pusa lista (+ 11 (BLABLA 23 3.2) 10) care include lista cu eroarea. Trebuie sa retineti ca acest lucru se continua: daca si aceasta lista este inclusa in alta, se prezinta si aceasta, etc. Daca indicarea este profunda, veti primi multe linii care contin liste peste liste, din ce in ce mai largi. Este ca si cand, privind la microscop un tesut bolnav, vi s-ar prezenta mai intai celula bolnava, apoi microscopul s-ar departa si a-ti vedea tesutul cu celula bolnava in el, apoi organul cu tesutul cu celula bolnava, etc. Este clar ca cel mai interesant este mesajul de eroare, apoi lista "cea mai interoioara", iar restul, nu face decat sa localizeze problema in ansamblu. Nenorocirea este ca toate acestea fug pe ecran si putem pierde exact partea interesanta, adica inceputul. Pentru a "ingheta" defilarea aveti la dispozitie tasta PAUSE (undeva sus - dreapta), dupa care pentru a o relua puteti apasa orice tasta. Oricum, e nevoie de agilitate. Asta va mentine tineri, iata deci inca un avantaj. O sa va intrebati cat de multre liste exterioare va sunt prezentate. Va spun eu: maxim 100. Fix 100, nici mai multe nici mai putine. Adica stati, pot fi mai putine doar daca profunzimea implicarii listelor din programul dvs. nu atinge acest nivel, OK?
Volatilitatea
A scrie linii de program AutoLISP in felul aratat se justifica doar pentru mici incercari, "rutinute", "functioare", "programele". Daca aveti un program mai mare va veti chinui sa-l introduceti linie cu linie si, tocmai bine cand ati imperecheat si ultima paranteza veti primii un mare si urat mesaj de eroare, totul "fasaindu-se". Veti afla, eventual, unde si ce ati gresit, dupacare va trebui sa o luatI de la capat. De ce? Pentru ca totul e volatil. Cum sa facem ca sa nu mai fie asa?
Putem scrie progarmul nostru sub forma unui fisier in afara AutoCAD-ului. Pentru aceasta va fi necesar sa folosim un editor de texte, ca de exemplu NORTON Editor (ne.com, descris in sectiunea ce urmeaza). Odata creat acest fisier, el trebuie transmis AutoLISP-ului.
Sa presupunem ca am creat fisierul "calcul.lsp" cu continutul:
Am facut asta, asa cum spuneam in afara AutoCAD-ului. Acum lansam AutoCAD-ul sI primim prompterul obijnuit, pe care vom da "comanda" :
Command: (load "calcul")
Command:
Se observa ca "programul" a fost incvarcat sI s-au evaluat toate listele implicate, returnandu-se rezultatul, dupa care apare iar prompterul obijnuit. Puteti acum sa imbunatatiti progarmul, sa-l extindeti, etc. Totusi, este incomod sa parasim AutoCAD-ul pentru a edita fisierul si a reveni iar in AutoCAD pentru a vedea efectele. Ei bine, se poate lucra si din interiorul AutoCAD-ului cu un editor de texte.
Dupa ce reveniti in AutoCAD, daca ati facut modificari in fisier veti da iar "comanda" (load "nume"), reancarcand programul AutoLISP si observand efectele. Se economiseste astfel enorm de mult limp.
Pentru a raspunde la intrebare, va voi pune eu una: ce diferenta este intre proiectarea asistata si desenare asistata ? Raspunsul este ca desenarea foloseste mijloace directe pentru a transpune ideile in desene, ca si cand in loc de calculator s-ar folosi o planseta (cu facilitati suplimentare notabile). In schimb, proiectarea asistata depaseste acest cadru, exploatand forta calculatorului sub aspecte multiple: generare de desene (prin program), calcule geometrice, de rezistenta, etc.
Daca dorim sa facem calcule, sa generam desene parametrizate (in care diverse dimensiuni sunt cerute de la tastatura), sa scapam de desenarea respectiva etc. putem introduce intr-un program intreaga reteta de actiuni. Ne vom ocupa in prima etapa de posibilitatea de a face calcule.
Elemente de limbaj AutoLISP.
In exemplul prezentat in capitolul anterior, unde aparea lista (* 23 3.2), spunem ca semnul "*" reprezinta numele functiei inmultire, iar 23 si 3.2 sunt argumentele acestei functii. Practic, aceasta este o expresie. In generea, expresiile AutoLISP au sintaxa:
(nume-funct [argumente] . )
Separatia intre numele functiei si argumente, ca si intre argumente este un spatiu (blanc). Orice argument poate fi la randul lui o expresie. Parantezele drepte [ ] indica faptul ca ceea ce se afla cuprins intre ele este obtional; deci pot fi si functii fara argumente. In exemplul (* 23 3.2) argumentele sunt constante; unul este intreg iar celalalt este real.
In loc de constante, insa, se poate lucra cu variabile. Acestea, ca si in algebra, sunt exprimate literal. Practic, va puteti cand la variabile ca la niste sertare: pe sertar este pusa o eticheta (numele variabilei), iar in sertar se afla valoarea ei.
Tipurile posibile de variabile in AutoLISP sunt 4, (intr-o prima aproximare):
INTREG = numere imtregi cu semn;
REAL = numere cu partea intreaga si zecimala, cu semn;
PUNCT = lista de doua sau de trei variabile reale reprezentand coordonatele unui punct geometric.
SIR = secventa de caractere cuprinse intre ghilimele
Tipul variabilei este asociat automat cu aceasta, potrivit valori care i se atribuie. Daca ulterior i se atribuie alta valoare, de alt tip, se va schimba si tipul variabilei. Numele variabilei poate fi ales liber de catre dumneavoastra. Singurele restrictii sunt legate de necesitatea ca primul acracter sa fie o litera si de faptul ca, intotdeauna, este predefinita variabila p (notata cu pi sau PI), cu valoarea cunoscuta: 3.141593.
Cum facem sa cream o noua variabila? Foarte simplu: atribuind unui nume o valoare. Functia de atribuire in AutoLISP este "SETQ". Ea este similara cu "LET" din BASIC, "=" din FORTRAN sau ":=" din PASCAL, pentru cine cunoaste unul din aceste limbaje. Sintaxa:
(setq nume-var valoare snume-var valoaret . )
unde:
nume-var = numele liber ales de dumneavoastra pentru variabila
valoare = valoarea pe care doriti sa o atribuiti variabilei; tipul ei va conferi un tip similar variabilei definite cu aceasta ocazie.
Se observa ca se pot defini mai multe variabile succesiv.
Exemple:
(setq a 23)
(setq x1 2.3)
(setq pers "Costache cel bun")
(setq u 3 w 4.5 abc "flansa")
Variabila a va fi de tip intreg si va avea valoarea 23. Variabila x1 va fi de tip real si va avea valoarea 2.3, iar variabila pers va fi de tip sir, cu valoarea "Costache cel bun" (de retinut ca ghilimelele nu fac parte din sir).
In ultimul exemplu s-au definit simultan variabilele u, w si abc. Aceasta poate fi scris mai frumos:
(setq u 3
w 4.5
abc "flansa")
Punand cate o variabila pe o linie, ca sa fie mai clar.
La variabilele reale trebuie retinut ca se impune ca punctul zecimal sa aiba si de o parte si de alta cate o cifra, chiar si daca e zero (deci nu se admit 2 ci 2.0, si nu .4 ci 0.4). Chiar daca uneori merge, nu contati pe asta.
Daca acum dati:
(setq pers x1)
veti schimba tipul variabilei pers din sir in real si-i veti atribui valoarea pe care o are variabila reala x1. Ca sa continuam exemplul cu sertarele, este ca si cand ati pune sertarul pers deasupra lui x1 si i-ati scoate fundul; cand cautati ceva in pers, gasiti ceea ce se afla in x1.
Sa vedem cum e cu variabilele de tip punct geometric,pe care le-am lasat special la urma. Acestea contin coordonatele X,Y sI, optional, Z. Practic, e vorba de liste de doua sau trei reale cuprinse intre paranteze, ca in:
Valorile corespund in ordine coordonatelor X,Y,Z. Daca Z lipseste, valoarea sa se ia potrivit contextului (daca ELEVatia curenta e 20.0, se ia aceasta valoare, nu ?). Pentru a forma o lista cu sens LISP, trebuie folosita functia "LIST", sub forma:
(list 1.2 23.0)
(list 22.5 0.23 12.34)
Pentru a crea o variabila punct, vom atribui unui nume liber ales o astfel de lista, ca in:
(setq pct1(list 1.2 23.0))
(setq pct2(list 22.5 0.23 12.34))
(setq pct3(list x1 1.0 2.0))
In al treilea exemplu s-a folosit dreptcoordonata X variabila x1 definita anterior.
Ca alternativa, se poate folosi prefixul apostrof, care face ca ceea ce urmeaza sa fie luat ca atare, fara a fi evaluat. Astfel, puteti pune:
(setq pct2 '(22.5 0.23 12.34))
definind identic punctul pct2 ca mai sus.
Va dati seama care este substratul? Daca n-ar fi apostroful, s-ar evalua lista interna (care n-ar duce la nimic bun..) si apoi cea externa. Daca e pus apostroful, lista interna ramane neevaluata si se trece la evaluarea celei externe, care va atribui numelui pct2 o lista si nu o simpla valoare (scalara, as zice). Ce este neplacut este ca nu putetI folosi apostroful la inceput decat intr-un program scris ca fisier, deoarece daca introduceti linii pe promterul "Command:", apostroful nu e acceptat cu acest sens, ci cu sensul de comanda "transparenta".
Pe de alta parte este evident ca nu putem folosi apostroful punand in lista altceva decat valori constante. De ce? Pentru ca acestea sunt atribuite orbeste, fara a fi interpretate in vreun fel, or atunci cand punem un nume de variabila cum ar fi "xmin" ne gandim la valoarea care se afla in spatele ei, si nu la literele "x", "m", "i", "n". Ba nici numele "PI" (care este al unei constante) nu poate fi folosit. De fapt, aceasta functie "apostrof" este sinonima functiei "quote", care poate fi folosita la fel de bine, dar vedeti, asa ne intindem si diluam continutul .
Avem timp si pentru asta.
Invers, pentru a extrage coordonatele unui punct, vom folosi una dintre functiile "car", "cadr" sau "caddr":
(car pct1)
(cadr pct1)
(caddr pct3)
Prima returneaza coordonata X a punctului pct1 (adica 1.2), a doua Y-ul lui pct1 (adica 23.0), iar a treia Z-ul lui pct3 (adica 2.0).
Daca doriti sa definiti un punct pcta care sa aiba X-ul lui pct1 si Y-ul lui pct2, veti pune:
(setq pcta (list (car pct1) (cadr pct2)))
in acest fel pcta va avea coordonatele (1.2 0.23)
Iata ca acum stim sa definim orice tip de variabila. Cum putem sa le folosim? Pentru a folosi o variabila AutoLISP definita ca mai sus veti pune pur si simplu un semn de exclamatie in fata variabilei.
Un prin exemplu este dat in continuare:
Command: (setq raza 11)
command: fillet
polyline/radius/<Select two objects>: r
enter fillet radius <0.0000>: raza
Command:
Am definit cu "setq" variabila raza dandu-i valoarea 11; apoi am dat comanda "fillet" in AutoCAD si cand ni s-a cerut raza, am raspuns dand numele variabilei raza precedat de " Asta a facut ca AutoCAD sa-si ia valoarea de memorie, cercetand continutul variabilei raza (adica al sertarului) atribuit de noi.
Iata un exemplu:
Command: (setq p1 `(10 20) p2 `(30 40))
Command: line
From point: p1
To point: p2
To point: <enter>
Command:
Ce s-a intamplat? S-a trasat o linie de la punctul (10 20) la punctul (30 40). Daca va uitati mai atent la dialog(folosind eventual tasta F1), veti vedea ca mai intai se atribuie valori de punct variabilelor p1 si p2 intr-o singura linie "setq". Apoi se da comanda "line" care cere puncte; i se furnizeaza p1 si p2, adica i se comunica AutoCAD-ului sa ia coordonatele acestor doua puncte din listele asociate variabilelor p1sI p2.
Iata deci ca noi am definit niste nume simbolice (raza, p1,p2) care sunt deja cunoscute. Trebuie spus aici ca de fapt, inca de cand intram in AutoCAD sunt deja definite niste nume simbolice, cele pe care le definim noi adaugandu-se la acestea. Practic este vorba de o lista de nume simbolice. Aceasta lista are si ea un nume: atomlist. Daca doriti sa-i vedeti continutul, introduceti direct atomlist ca raspuns la prompterul "Command:" al AutoCAD-ului; mai intai apasatI tasta <F1> pentru a trece in mod text, deoarece ecranul se va umple pe trei sferturi cu nume de simboluri. Iata cam cum va aparea aceasta lista:
(INTERS GRREAD GRTEXT .
. STRLEN PI MINUSP ZEROP .
COS ATAN 1 1+ABS MAX .
REM * + ASSOC MEMBER .
EXPAND ATOMLIST)
Pare instructiv, nu-i asa ?. Veti vedea ca numele date de Dvs. Vor aparea primele in aceasta lista.
Numele simbolic atomlist depinde de versiunea (Release) astfel:
Release-10, -11 = atomlist
Release-12, -13 = atoms-family
Odata cu introducerea numelui atoms-family variabila s-a transformat intr-o functie, astfel ca acum trebuie introdus:
(atoms-family 0)
pentru a obtine efectul pe care il dadea atomlist
Expresii AutoLISP
Cum, necum, iata ca am aflat sensul catorva functii AutoLISP: setq, list, car, cadr, caddr. Acestea sunt folosite pentru a forma expresii AutoLISP, potrivit sintaxei de acum cunoscute:
(nume-funct sargumentet . )
Expresiile AutoLISP pot fi:
matematice
sir
conditionale
Ele sunt descrise mai jos. Inarmati-va cu rabdare, intelegeti-le si probati-le: veti vedea ce forta teribila va ofera Iar acesta este doar varful aisbergului .
Expresii matematice
Expresiile matematice folosesc functii ale caror argumente pot fi cel mai des reale sau intregi; daca macar unul e real, atunci toti intregii vor fi avansati la real si rezultatul va fi real.
O prima categorie de functii ce intra in compunerea expresiilor matematice este:
(+ x y) returneaza suma x+y;
(- x y) returneaza diferenta x-y;
(* x y) returneaza produsul x8y;
(/x y) returneaza catul x/y;
(max x y) returneaza maximul dintre x sI y;
(min x y) returneaza minimul dintre x sI y.
Observati de fiecare data ca imediat dupa fiecare paranteza (fara vreun blanc) urmeaza numele functiei, apoi blanc si argumentele; dupa ultimul argument urmeaza paranteza inchisa. Sa aveti grija sa respectati aceste reguli, pentru ca programele Dvs. Sa para mereu ordonate. In particular, la aceste functii argumentele pot fi mai multe decat doua. De exemplu:
returneaza 2.5
(max 100 60 112 1.2) returneaza 112.0
Observati ca ultimul rezultat este real deoarece, chiar daca maximul nu este real, comparatia dintre argumente a dus la transformarea celor intregi la reale datorita lui 1.2. Este demn de retinut ce se intampla la calculul amestecat cu intregi si reale. De exemplu, stiind ca trecerea de la grade la radiani se face prin coeficientul p/180, daca veti converti 60 de grade la radiani prin expresia:
(* (/ 60 180) pi)
gandind ca se imparte intai 60 la 180 iar apoi rezultatul (care ar fi 0.3333) se inmulteste cu p, veti constata ca rezultatul este taman zero De ce? E simplu: pentru ca impartirea lui 60 la 180 face, intradevar 0.33333 dar ambele argumente fiind INTREGI, atunci si rezultatul se converteste la intreg, dar nu prin rotunjire ci prin TRUNCHIERE. Chiar daca impartiti 179 la 180 obtineti tot zero Ce e de facut? Puteti pune unul din argumente ca real (de exemplu 60.0 in loc de 60) sau puteti sa ordonati socotelile astfel:
(* (/ pi 180) 60)
Alte functii matematice cer argumente mai putine. Iata-le, impreuna cu numarul exact de argumente necesare si cu valorile returnate:
(abs x) . . . . . . . . . valoarea absoluta a lui x;
(sqrt x) . . . . . . . . . radical din x;
(expt x p) . . . . . . . . x la puterea p;
(exp p) . . . . . . . . . e la puterea p;
(log x) . . . . . . . . . .ln x (sau logaritm in baza e a lui x);
(float x) . . . . . . . . ..valoarea intregului x convertit la real;
(fix x) . . . . . . . . . .valoarea realului x trunchiata la intreg; din 2.6 se obtine 2, din -2.6 se obtine -2;
(sin alfa) . . . . . . . . sinus de alfa (dat in radiani);
(cos alfa) . . . . . . . . cos de alfa (dat in radiani);
(atan x) . . . . . . . ..arctangent (in radiani) de x;
(1+ x) . . . . . . . . ..x marit cu 1; echivalent cu (+ x 1);
(1 - x) . . . . . . . . ..x redus cu 1; echivalent cu (- x 1);
(angle p1 p2) . . unghiul in radiani al segmentului p1-p2 masurat potrivit sensului si originei unghiurilor curent stabilite cu comanda UNITS (de obicei trigonometric);
(distance p1 p2) . ..distanta dintre punctele p1 si p2;
(polar p1 alfa dist) ..punctul aflat la "dist" si unghiul "alfa"(in radiani) fata de punctul dat p1;
(type a) . tipul variabilei a (integer=intreg, real=real, list=lista, string=sir).
Se observa ca nici una dintre functiile prezentate nu schimba valoarea variabilei pe care se aplica; ele calculeaza, pur si simplu, o valoare si o returneaza. De exemplu, (sin x) afla care este valoarea variabilei x, aplica pe aceea valoare functia sinus( considerand-o ca unghi dat in radiani) si returneaza rezultatul. Valoarea lui x nu s-a schimbat. Daca doriti Dvs. Sa inlocuiti pe x cu sinusul sau, puteti sa faceti o atribuire de genul (setq x (sin x)). Cum si-o face omul cu mana lui . .
Functii sir
Atentie ca nu am scris "expresii sir", ci "functii ;ir". Asta ca prezentam doar functiile cu efect asupra sirurilor:
(itoa int) . . . . . conversia valorii variabilei int in sir ASCII;
(atoi s) . . conversia intreaga a sirului s;
(ascii c) . . . .codul ASCII (intreg) al caracterului c;
(chr int) . ..caracterul ASCII corespunzator codului int;
(strcat s1 s2) . . sirul s1 concatenat cu s2;
(strlen s) . ..lungimea sirului s;
(terpri) . .incepe o noua linie pe ecran.
Exemple:
(atoa 123) . . . returneaza sirul "123", deci in loc de un intreg gasim un sir;
(atoi "123") . . returneaza intregul 123;
(ascii "A") . . ..returneaza 65, codul ASCII al lui A;
(chr 65) . . .returneaza A;
(strcat "retea" "-apa") . returneaza sirul "retea-apa";
(strlen "retea-apa") . . returneaza lungimea 9 a sirului anterior.
Expresii conditionale.
Un adevarat program de calculator nu face numai calcule, ci ia si decizii, functie de valorile momentane ale diferitelor variabile. O cale pe care orice limbaj de programare o ofera este decizia if ("daca"). Ea prezinta o ramificatie in program de forma:
"Daca expr-cond atunci executa1 altfel executa2"
unde expr-cond este o expresie conditionala, ale carei valori pot fi true(adevarat) sau false(fals). In AutoLISP vom conveni sa nota adevarat prin T, iar fals prin nil. Ca efect, daca expr-cond este T, se executa actiunea executa1, iar daca e nil, se executa actiunea executa2. Actiunile exprimate de executa2 pot sa lipseasaca, astfel incat, ori se produc actiunile executa1 ori nimic. Ca urmare, functia if poate avea una din formele:
(if expr-cond executa1)
(if expr-cond executa1 executa2)
Se observa ca actiunile din executa2 pot fi pur si simplu adaugate, daca se doreste acest lucru, fara a exista un separator gen atunci. Daca tinem cont ca actiunile in AutoLISP sunt date prin expresi continute in liste ce pot fi oricand imbricate oricat de profund unele in altele, ne dam seama ca ceea ce apare mai sus sub numele executa1, de exemplu, este de fapt o lista. Ne concentram acum pe expr-cond. Am spus ca valoarea acestei expresii poate fi T sau nil. Atat !
Pentru a o construi, putem folosi una sau mai multe dintre urmatoarele functii(aici nu sunt date decat cele mai utile, restul mai incolo):
(minusp num) . ..T daca num e negativ, nil altfel
(zerop num) . . .. T daca num e zero, nil altfel
(numberp x) . . . . T daca x e numar(real sau intreg), nil altfel
(not a b . ) . ..NU logic aplicat pe a,b, .
(or a b . ) . SAU logic aplicat pe a,b, .
(and a b . ) . .SI logic aplicat pe a,b, .
( = a b ) . . . T daca a este egal cu b, nil altfel
( /= a b) . . . T daca a este neegal cu b, nil altfel
( > a b ) . . . T daca a este mai mare ca b, nil altfel
( >= a b) . . . T daca a este mai mare sau egal cu b, nil altfel
( < a b) . . . T daca a este mai mic ca b, nil altfel
( <= a b) . . .. T daca a este mai mic sau egal cu b, nil altfel
( listp a) . . . T daca a este o lista, nil altfel
( null a) . . . T daca a estenil, nil altfel
Observati ca vi se ofera calea de a testa valorile diferitelor variabile pentru ca, functie de rezultat, sa luati o decizie. De exemplu, daca doriti ca variabila sir stare sa ia valoarea "OK" daca variabila intreaga ii este nula, si valoarea "GRESIT" in orice alta situatie puteti concepe o expresie de genul:
(if (= ii 0) (setq stare "OK") (setq stare "GRESIT"))
unde expresia conditionala este (= ii 0), actiunile executa1 sunt date de (setq stare "OK") iar actiunile executa2 de (setq stare "GRESIT"). Acelasi lucru poate fi scris mai compact:
(setq stare (if (= ii 0) "OK" "GRESIT"))
Se vede ca aici expresia if returneaza fie valoarea "OK", fie "GRESIT", dupa valorile lui ii (evaluarea listei formata de expresia if trebuie sa returneze ceva.). Este mai elegant dar mai greu de urmarit. Alegeti .
Fiind in AutoCAD, putem folosi foarte bine pentru teste valorile variabilelor de sistem. In acest scop exista functia AutoLISP getvar, care afla ce valoare are orice variabila de sistem. Sintaxa ei este:
(getvar nume-var)
Puteti construi o expresie de genul:
( if ( > (getvar "FILLETRAD") 8.3 (setvar "GRIDEMODE" 0"))
Aici getvar obtine valoarea razei de racordare curente (FILLETRAD) si, in cazul in care este mai mare ca 8.3, elimina reteaua de puncte ajutatoare(GRID-ul). Dupa cum se vede, acest lucru se face utilizand o alta functie AutoLISP, setvar, a carei sintaxa este:
(setvar nume-var valoare)
Prin ea, variabila GRIDEMODE este facuta 0 (daca raza de racordare este mai mare de cat 8.3). Se vede ca de aici lipseste cu totul secventa executa 2.
Copyright © 2024 - Toate drepturile rezervate