# Úvod do programování

## Základní programové konstrukce

for variable: initial_value step increment thru limit do body 

initial_value, increment, limit, a body mohou být libovolné výrazy.

for i:1 thru 5 step 1 do display(i)$

i;

Pokud je přírůstek jedna může se step vynechat.

for i:1 thru 5 do print(i)$

total : 0;

for i:1 thru 5 do total : total +i$

total;

for i:2 thru 6 step 2 do print('sum(j^i,j,1,n))$

i;

seznam : [1,2,3,4,5];

s:0;

for i:1 thru length(seznam) do
if remainder(seznam[i],2)=0 then
s:s+seznam[i]^2;

print("soucet ctvercu s = ", s);

for variable in list end_tests do body

kill(all);

s:0;seznam : [1,2,3,4,5];

for i in seznam do if remainder(seznam[i],2)=0 then
s:s+seznam[i]^2;

print("soucet ctvercu s = ", s);

for variable: initial_value step increment while condition do body 

s : 0$

for i:1 while i<=10 do s:s+i;

s;

while ... do ... (unless ... do ...)

while provadi opakovane posloupnosti prikazu tak dlouho, pokud je podminka splnena 
(tedy pokud je logicky vyraz typu true). Pokud ma podminka hned na zacatku hodnotu false, 
posloupnost prikazu se neprovede.

x : 256;

while x>1 do x: x/4;

x;

x : 1/2;

while x>1 do x: x/4;

x;

Eukliduv algoritmus

a:20$ b:12$
while notequal(b,0) do (
 d:remainder(a,b),
 a:b,
 b:d)$

print("celociselny NSD je", a);

gcd(20,12);

kill(all);

 block([x1,x2,...,xn],exp1,exp2,...,expn)

Posloupnost příkazů, která se navenek chová jako jeden příkazů. 
[x1,x2,...,xn] je posloupnost lokálních proměnných. Výsledem je výsledek posledního příkazu posloupnosti.
Block příkazů může být ukončen i pomocí return(x), x bude poté výsledkem bloku.

euklid(a,b):=
 block([],local(d),d:remainder(a,b),
 while notequal(d,0) do
 (a:b, b:d, d:remainder(a,b)), b);

euklid(20,12);

Funkce, ktera vrací největší mocnimu dvou menší nebo rovnou zadanému n.

binpow(n):=block([],
local (x,m),
x:0,
m:n,
while m>=1 do
(m:m/2,x:x+1), x-1);

binpow(8);

for n:1 thru 8 do print(n, binpow(n));

if cond_1 then expr_1 else expr_0

x : -2;

if x < 0 then 0 else 1;

x : %pi;

if x < 0 then 0 else 1;

if cond_1 then expr_1 elseif cond_2 then expr_2 elseif ... else expr_0 

if x < 0 then -1 elseif x = 0 then 0 else 1;

x : 0;

if x < 0 then -1 elseif x = 0 then 0 else 1;

Následující příkaz vyplňuje horní trojúhelníkovou matici řádkovými indexy,
část pod hlavní diagonálou sloupcovými indexy a hlavní diagonálu jedničkami.

for i:1 thru 4 do
for j:1 thru 4 do
if i<j then A[i,j]:i
elseif i>j then A[i,j]:j
else A[i,j]:1;

listarray(A);

arrayinfo(A);

Nalezne první hodnotu, která není prvočíslo v posloupnosti 2^i-1, i=3,5,7,.. 
a jakmile ji najde, přeruší výpočet.

for i: 3 step 2 do
if primep(2^i-1)
then print(2^i-1, "je prvocislo")
else return(2^i-1);

## Uživatelem definované funkce

Jednoduchý program v Maximě není nic jiného než posloupnost příkazů, např.

tangent(fn, x) :=
       diff(fn(x), x) / ((diff(fn(x), x) * diff(fn (x), x))^(1/2));

Tento zápis má jednu nevýhodu, třikrát zde počítáme tu samou derivaci. 
Výhodnější je tento zápis.

tangent(fn, x) :=
  block ( [df: diff(fn(x), x)],
           df / (df * df)^(1/2)
        );

Příkaz block je vlastně tělem procedury, proměnné definované uvnitř jsou lokálními
proměnnými.

max3(a,b,c) := 
 block([], print("nalezeni maxima z cisel ",a,b,c),
 if a<b then
 if b<c then c else b 
 elseif a<c then c
 else a)$

Procedura vrací poslední vyhodnocenou hodnotu.

max3(3,2,1);

save("/home_zam/plch/vyuka/maxima/maximum", max3);

Zápis je proveden v jazyce LISP.

kill(all);

load("/home_zam/plch/vyuka/maxima/maximum");

max3(3,2,1);

kill(max3);

Program (proceduru) můžeme napsat i textovým editorem, pak k jejímu načtení 
použijeme příkaz batch. 

batch("/home_zam/plch/vyuka/maxima/procedura.mac");

max3(2,3,1);

Procedury s proměnným počtem parametrů

prog([l]) := block([],
  print ("l se sklada z", l, "a pocet prvku je", length(l)))$

prog(a,b,c,d);

kill(all);

maxN([l]):=block([result],
 if length(l)>0
 then
 result:l[1],
 for i:2 thru length(l) do
                if l[i]>result then    result:l[i], return(result))$

maxN(9,2,3,4,5.0);

result;

Lokální proměnné

g(x):=1-x;

g(100);

block (local (g), g(x) := 2 * x, g(100));

g(100);