155GIT1 / 5. cvičení: Porovnání verzí

Z GeoWikiCZ
mBez shrnutí editace
Řádek 1: Řádek 1:
{{Geoinformatika}}
{{Geoinformatika}}
{{Cvičení|155GIT1|5|Algoritmizace, podmínky a cykly}}
{{Cvičení|155GIT1|5|Uživatelské funkce}}


== Náplň cvičení ==
== Náplň cvičení ==


# zobrazení zpráv, zadaní vstup
# uživatelské funkce
# podmínky (<tt>if, else, elseif, end, all, any</tt>)
# chybová hlášení, nápověda k funkci
# větvení (<tt>switch</tt>)
# drobné smíšené úlohy
# podmínky (<tt>for, while</tt>)
# příkazy <tt>break, continue</tt>
# složené podmínky


== Ukázky ==
== Ukázky ==


=== Interaktivní vstup ===
=== Uživatelské funkce ===
 
'''Syntax'''
function [vystup1,vystup2,...,vystupn] = nazev(vstup1,vstup2,...,vstupn)
end  % end neni povinne
 
Každá funkce musí být uložena ve vlastním souboru s příponou <tt>.m</tt>. Název souboru musí odpovídat názvu funkce! Klíčové slovo <tt>function</tt> musí být na prvním řádku souboru.


<source lang=octave>
<source lang=octave>
  disp('Program vyzaduje vstup');
  function [min_x, max_x, mean_x] = stat(x)
a = input('Zadejte cislo a: ')
 
    min_x = min(min(x));
    max_x = max(max(x));
    mean_x = mean(x(:));    % stejny vysledek jako mean_x = mean(mean(x))
 
end
</source>
</source>


=== Vyhodnocování relačních výrazů, all, any ===
'''Příklad volání'''


* pravdivá relace je vyhodnocena jako 1
* nepravdivá relace je vyhodnocena jako 0
* funkce '''all()''' (uvažujme např. vícero výsledků relačních výrazů současně)
<source lang=octave>
all([1 1 1])
all([0 0 1])
all([0 0 0])
</source>
* funkce '''any()''' (uvažujme např. vícero výsledků relačních výrazů současně)
<source lang=octave>
<source lang=octave>
  any([1 1 1])
  data = rand(5)
  any([0 0 1])
  [mi, ma, mn] = stat(data);
  any([0 0 0])
  fprintf('min  = %.3f\nmax  = %.3f\nmean = %.3f\n', mi, ma, mn)
</source>
</source>


=== Větvení (if) ===
=== Chybová hlášení, nápověda ===


* [http://geo.fsv.cvut.cz/user/gin/git1/matlab.pdf#page=71 přednášky]
<source lang=octave>
function [min_x, max_x, mean_x] = stat(x)
% vypocet minimalni, maximalni a prumerne hodnoty matice


<source lang=octave>
    if any(any( imag(x)>0 ))
% skalarni podminka
        error('stat: Vstupni matice obsahuje imaginarni cisla.')
a = randi(10)
    end
b = randi(10)
    min_x = min(min(x));
    max_x = max(max(x));
    mean_x = mean(x(:));


if a < b
    disp('a je mensi nez b');
else
    disp('a je vetsi nebo rovno b');
  end
  end
</source>


% vektorova podminka
Vyvolání nápovědy k uživatelské funkci:
a = [1 2];
                         
  b = [0 3];
<source lang=octave>
  help stat
</source>


if a < b  % vyhodnoti se jako:  if all(a < b)
Volání funkce (chybná vstupní data):
    disp('a je po prvcich vzdy mensi nez b');
   
  else
<source lang=octave>
    disp('a je po prvcich alespon jednou vetsi nez b');
  data1 = [data, 5+2i * ones(5,1)]
  end
  [mi, ma, mn] = stat(data1)
 
% test na (ne)nulove prvky promenne (promenna obvykle obsahuje vysledky relacnich vyrazu, tj. 0 ci 1)
  if b      % totez jako:  if all(b)
    disp('b neobsahuje zadne nulove cleny');
elseif a  % totez jako:  if all(a)
    disp('b obsahuje nulovy clen, a neobsahuje zadne nulove cleny');
else
    disp('a i b obsahuji nulovy clen');
end
   
if any(b)
    disp('b obsahuje alespon jeden nenulovy clen');
end
</source>
</source>


=== Větvení (switch) ===
=== Příkaz return ===
* je-li v běhu funkce vykonán příkaz <tt>return</tt>, je okamžitě činnost funkce ukončena (bez vykonání evtl.dalších příkazů) a na pozici jejího volání jsou vráceny aktuálně vypočtené hodnoty výstupních parametrů funkce


<source lang=octave>
=== Drobné úlohy ===
cislo = randi(10)


switch cislo
'''Funkce pro výpočet nekonečné řady do zadané přesnosti (příklad iterativního výpočtu)'''
  case 1
    disp('cislo je 1')
  case {2,3}
    disp('cislo je 2 nebo 3')
  case {4,6,7}
    disp('cislo je 4, 6 nebo 7')
  otherwise
    disp('cislo je 5 nebo vetsi nez 7')
end
</source>


=== Cyklus for ===
např. výpočet funkce arctg(), viz {{wikipedia|Taylorova řada}}:


<source lang=octave>
<source lang=octave>
% tvorba vektoru
function [arctgx] = arctg(x,mez)
  n = 4
  % vypocet funkce arctg rozvojem v radu do zadane presnosti
  for i = 1:n
  % IN: x      ... vektor argumentu funkce
     a(i) = i^2
%     mez    ... zadana presnost vypoctu
  end
  % OUT: arctgx ... vektor vypoctenych uhlu z intervalu <-pi/2,pi/2>


% tvorba matice
  if any(x > 1) | any(x < -1)
  m = 4  % pocet radku
     error('arctg: Vstupni hodnoty musi byt z intervalu <-1,1>.')
n = 3  % pocet sloupcu
for i = 1:m
     for j = 1:n
        A(i,j) = i+j
    end
  end
  end


% priklad - v matici vyhledat sude radky (jedna z moznych variant zapisu)
% vypocet pro kazdy prvek daneho vektoru samostatne
A = rand(5,4)
  for i=1:length(x)
  for i=1:size(A,1)
     % start iterace pro i-ty vstupni prvek
     if rem(i,2) == 0        % rem(a,b) ... zbytek po deleni cisla a cislem b
    y0 = 100; % vkladam fiktivni hodnotu, kterou x na vstupu nikdy nemuze nabyt
        A(i,:) = -1 * A(i,:)
    % 1.iterace
    n = 1;
    y = x(i);
    while  abs( y-y0 ) > mez
        % n-ta iterace
        n = n+1;
        y0 = y;
        y = y0 + (-1)^(n+1) * x(i)^(2*n-1)  / (2*n-1);
     end
     end
    % ulozeni vypoctene hodnoty do vystupni promenne
    arctgx(i) = y;
    fprintf('Pocet iteraci vypoctu: %d\n',n)
  end
  end
</source>
</source>


=== Cyklus while ===
'''Funkce pro načtení neformátovaných dat po řádcích'''
 
např. záměna čárky za tečku:


<source lang=octave>
<source lang=octave>
  a = 1;
  function teckazacarku(file)
  b = 5;
  % vyhleda vsechny carky v souboru a zameni je za tecku
while a < b
  % IN: file ... jmeno vstupniho souboru (textovy retezec)
    a
    a = a + 1;
  end
</source>


=== Příkazy break, continue ===
  if ischar(file) == 0
 
     error('Jmeno vstupniho souboru musi byt textovy retezec.');
<source lang=octave>
  for i = 1:5
    if i == 2
        continue;
    end
     if i == 4
        break;
    end
    fprintf('i = %d\n', i);
  end
  end
</source>


=== Složené podmínky ===
vstup = fopen(file,'r');


''' logické AND ''' - všechny podmínky musí platit současně
filenew = [file(1:end-4), '_upr', file(end-3:end)];  % jmeno noveho souboru
vystup = fopen(filenew,'w');


<source lang=octave>
  konec = 0; % indentifikator konce souboru
% iterativni proces skonci jiz pri splneni jedne z pozadovanych presnosti
  while konec==0
  dx = 10;   % presnost v souradnici x - apriorni hodnota
    radek = fgets(vstup);  % fgets() nacte 1 radek souboru (se znakem \n)
  dy = 10;  % presnost v souradnici y - apriorni hodnota
     for i=1:length(radek)
i = 0;     % citac iteraci
        if radek(i) == ','
  while dx > 0.1 & dy > 0.1  % pozadovana presnost pro obe souradnice - 0.1
            radek(i) = '.';
     i = i+1
        end
     dx = dx/2
    end
     dy = dy/5
     fprintf(vystup,'%s',radek);
     konec = feof(vstup);  % feof() vrati pro konec souboru hodnotu 1, jinak vraci hodnotu 0
  end
  end


% totez
  fclose all;
  dx = 10;   % presnost v souradnici x - apriorni hodnota
  fprintf('Data ulozena do souboru %s\n',filenew);
  dy = 10;  % presnost v souradnici y - apriorni hodnota
i = 0;    % citac iteraci
while all([dx > 0.1, dy > 0.1])   % totez:  while [dx > 0.1, dy > 0.1]
    i = i+1
    dx = dx/2
    dy = dy/5
end
</source>
</source>


''' logické OR ''' - musí platit alespoň jedna podmínka
datový soubor [ftp://athena.fsv.cvut.cz/ZFG/GIT1/carky.txt carky.txt] ke stažení
 
Volání funkce:


<source lang=octave>
<source lang=octave>
% iterativni proces skonci az po splneni vsech pozadovanych presnosti
  teckazacarku('carky.txt')
  dx = 10;  % presnost v souradnici x - apriorni hodnota
dy = 10;  % presnost v souradnici y - apriorni hodnota
i = 0;    % citac iteraci
while dx > 0.1 | dy > 0.1  % pozadovana presnost pro obe souradnice - 0.1
    i = i+1
    dx = dx/2
    dy = dy/5
end
 
% totez
dx = 10;  % presnost v souradnici x - apriorni hodnota
dy = 10;  % presnost v souradnici y - apriorni hodnota
i = 0;    % citac iteraci
while any([dx > 0.1, dy > 0.1])
    i = i+1
    dx = dx/2
    dy = dy/5
end
</source>
</source>


== Úlohy ==
== Úlohy ==


* [[155GIT1 / 5. cvičení / Příklady|5. cvičení - příklady]]
* [[155GIT1 / 6. cvičení / Příklady|6. cvičení - příklady]]
 
* [[155GIT1 / 7. cvičení / Příklady|7. cvičení - příklady]]

Verze z 26. 2. 2020, 17:36

Uživatelské funkce

Náplň cvičení

  1. uživatelské funkce
  2. chybová hlášení, nápověda k funkci
  3. drobné smíšené úlohy

Ukázky

Uživatelské funkce

Syntax

function [vystup1,vystup2,...,vystupn] = nazev(vstup1,vstup2,...,vstupn)

end  % end neni povinne

Každá funkce musí být uložena ve vlastním souboru s příponou .m. Název souboru musí odpovídat názvu funkce! Klíčové slovo function musí být na prvním řádku souboru.

 function [min_x, max_x, mean_x] = stat(x)

    min_x = min(min(x));
    max_x = max(max(x));
    mean_x = mean(x(:));    % stejny vysledek jako mean_x = mean(mean(x))

 end

Příklad volání

 data = rand(5)
 [mi, ma, mn] = stat(data);
 fprintf('min  = %.3f\nmax  = %.3f\nmean = %.3f\n', mi, ma, mn)

Chybová hlášení, nápověda

 function [min_x, max_x, mean_x] = stat(x)
 % vypocet minimalni, maximalni a prumerne hodnoty matice

     if any(any( imag(x)>0 ))
         error('stat: Vstupni matice obsahuje imaginarni cisla.')
     end
     min_x = min(min(x));
     max_x = max(max(x));
     mean_x = mean(x(:));

 end

Vyvolání nápovědy k uživatelské funkci:

 help stat

Volání funkce (chybná vstupní data):

 data1 = [data, 5+2i * ones(5,1)]
 [mi, ma, mn] = stat(data1)

Příkaz return

  • je-li v běhu funkce vykonán příkaz return, je okamžitě činnost funkce ukončena (bez vykonání evtl.dalších příkazů) a na pozici jejího volání jsou vráceny aktuálně vypočtené hodnoty výstupních parametrů funkce

Drobné úlohy

Funkce pro výpočet nekonečné řady do zadané přesnosti (příklad iterativního výpočtu)

např. výpočet funkce arctg(), viz Taylorova řada:

 function [arctgx] = arctg(x,mez)
 % vypocet funkce arctg rozvojem v radu do zadane presnosti
 % IN:  x      ... vektor argumentu funkce
 %      mez    ... zadana presnost vypoctu
 % OUT: arctgx ... vektor vypoctenych uhlu z intervalu <-pi/2,pi/2>

 if any(x > 1) | any(x < -1)
     error('arctg: Vstupni hodnoty musi byt z intervalu <-1,1>.')
 end

 % vypocet pro kazdy prvek daneho vektoru samostatne
 for i=1:length(x)
     % start iterace pro i-ty vstupni prvek
     y0 = 100; % vkladam fiktivni hodnotu, kterou x na vstupu nikdy nemuze nabyt
     % 1.iterace
     n = 1;
     y = x(i);
     while  abs( y-y0 ) > mez
         % n-ta iterace
         n = n+1;
         y0 = y;
         y = y0 + (-1)^(n+1) *  x(i)^(2*n-1)  / (2*n-1);
     end
     % ulozeni vypoctene hodnoty do vystupni promenne
     arctgx(i) = y;
     fprintf('Pocet iteraci vypoctu: %d\n',n)
 end

Funkce pro načtení neformátovaných dat po řádcích

např. záměna čárky za tečku:

 function teckazacarku(file)
 % vyhleda vsechny carky v souboru a zameni je za tecku
 % IN: file ... jmeno vstupniho souboru (textovy retezec)

 if ischar(file) == 0
     error('Jmeno vstupniho souboru musi byt textovy retezec.');
 end

 vstup = fopen(file,'r');

 filenew = [file(1:end-4), '_upr', file(end-3:end)];  % jmeno noveho souboru
 vystup = fopen(filenew,'w');

 konec = 0;  % indentifikator konce souboru
 while konec==0
     radek = fgets(vstup);  % fgets() nacte 1 radek souboru (se znakem \n)
     for i=1:length(radek)
         if radek(i) == ','
             radek(i) = '.';
         end
     end
     fprintf(vystup,'%s',radek);
     konec = feof(vstup);   % feof() vrati pro konec souboru hodnotu 1, jinak vraci hodnotu 0 
 end

 fclose all;
 fprintf('Data ulozena do souboru %s\n',filenew);

datový soubor carky.txt ke stažení

Volání funkce:

 teckazacarku('carky.txt')

Úlohy