|
|
3. Vytváření funkcí |
|
|
|
- Anti Motto: Všechno rozumné a užitečné bylo již vytvořeno.
Očekávaný následek: Nemá cenu nic nového vytvářet.
Hlavní následek: Všechno potřebné si koupím.
-
Pokud pochybujete o obecné platnosti předchozích výroků, je tato
kapitola určena právě vám.
- Motto: Čím hloupější sedlák, tím větší brambory. (české přísloví)
Programátorská analogie: ...tím delší funkce a ještě k tomu jedna.
- Funkce – pojmenovatelná posloupnost příkazů (porovnej s matematikou)
- Syntaxe:
function[vystupni_promenne]=jmeno(vstupni_promenne) |
jmeno – výstižné a jednoznačné, pod tímto názvem je nutno
funkci uložit jako soubor (s příponou *.m) !!!
vstupni_promenne - seznam vstupních parametrů, v
kulatých závorkách, čárka jako oddělovač
vystupni_promenne - seznam výstupních parametrů,
v hranatých závorkách, čárka jako oddělovač
seznamy parametrů mohou být prázdné
- komentář – začíná znakem % a končí s koncem řádku, nejen pro
osobní sklerózu, ale pomůže to i těm, kdo budou Vaše funkce
používat po Vás
program bez komentářů je jako velbloud bez hrbů, nedá se na něj dlouho dívat
první komentářový řádek – podstatné informace – hledání pomocí lookfor
druhý komentářový řádek – obecný popis komunikace s funkcí
další komentářové řádky – význam všech parametrů funkce a další informace
- dekompozice – rozklad systému na podsystémy (užitečný)
- modularita – složitou funkci vhodně dekomponujeme na několik jednoduchých funkcí
- Heslo semestru: Kdo nekrokuje s námi, krokuje proti sobě.
Poznámka 1: Pokud funkce musí fungovat, ale přesto nefunguje, krokuj.
Poznámka 2: Pokud funkce vypadá jako zcela nefunkční, ale přesto funguje,
krokuj.
Poznámka 3: Editor, debugger (Debug), F10, F11, F12, průzkum pomocí myši.
- Příkaz input
- Syntaxe:
promenna = input('vysvetlujici retezec znaku') |
Příklad: a = input('zadej a: ') |
|
|
|
|
Příklad 3A.1: |
|
|
Sestavte funkci na výpočet délky řemenice mezi dvěma koly.
Instrukce: náčrtek, odhad výsledku, středoškolská geometrie, krokování.
|
|
|
Řešení: |
|
|
function[l]=Remen(d1,d2,d) |
% Delka remenice mezi dvema koly |
% [l]=Remen(d1,d2,d); |
% l ... delka remenice |
% d1 ... prumer prvniho kola |
% d2 ... prumer druheho kola |
% d ... vzdalenost os kol |
r1=d1/2; r2=d2/2; |
% vypocet polomeru obou kol |
% delka rovneho useku remenice dle Pythagora: |
lsikmo=sqrt(d^2+(r2-r1)^2); |
% uhel mezi rovnym usekem remenice a spojnici os kol: |
phi=asin((r2-r1)/lsikmo); |
omega1=pi-2*phi; |
% stredovy uhel na prvnim kole |
omega2=pi+2*phi; |
% stredovy uhel na druhem kole |
l1=omega1*r1; |
% delka oblouku remenice na prvnim kole |
l2=omega2*r2; |
% delka oblouku remernice na druhem kole |
l=l1+l2+2*lsikmo; |
% uz je to tady |
|
|
|
|
Nalezení a spuštění funkce v dialogovém režimu: |
|
|
lookfor remenice
help Remen
type Remen
remen=Remen(1,1,10)
|
|
|
|
Příklad 3A.2: |
|
|
Sestavte funkci na výpočet geometrických charakteristik cirkusového
stanu s jedním hlavním stožárem a několika vedlejšími stožáry.
Vedlejší stožáry mají stejnou délku a jsou ekvidistantně rozmístěné
kolem hlavního stožáru. Vlastní plátno stanu je pak logicky tvořeno
stejným počtem trojúhelníků a lichoběžníků.
Instrukce: náčrtek, odhad výsledku, středoškolská geometrie, krokování.
|
|
|
Řešení: |
|
|
function [Q,P,L]=Cirkus(r,R,n,H,h) |
% Cirkusovy stan |
% [Q,P,L]=Cirkus(r,R,n,H,h); |
% Q ... plocha plaste stanu |
% P ... plocha zabrana stanem |
% L ... celkova delka vsech stozaru |
% r ... vzdalenost pomocnych stozaru od hlavniho stozaru |
% R ... vzdalenost mista ukotveni platna od hlavniho stozaru |
% n ... pocet vedlejsich stozaru |
% H ... vyska hlavniho stozaru |
% h ... vyska vedlejsich stozaru |
L=H+n*h; |
% uvaha pro male deti |
% uhel pod kterym jsou videny sousedni stozary od hlavniho: |
phi=2*pi/n; |
% vzdalenost vedlejsich stozaru podle kosinove vety: |
d=r*sqrt(2-2*cos(phi)); |
% vzdalenost kotev platna podle kosinove vety |
D=R*sqrt(2-2*cos(phi)); |
% delka horniho svu platna podle Pythagora |
hor=sqrt(r^2+(H-h)^2); |
% delka dolniho svu platna podle Pythagora |
dol=sqrt((R-r)^2+h^2); |
% vyska horniho trojuhelnika platna podle Pythagora: |
v=sqrt(hor^2-(d/2)^2); |
% vyska dolniho lichobeznika platna podle Pythagora: |
V=sqrt(dol^2-((D-d)/2)^2); |
% vyska trojuhelnika v pudorysu podle Pythagora |
W=sqrt(R^2-(D/2)^2); |
PT=d*v/2; |
% plocha horniho trojuhelnika platna |
PL=(D+d)*V/2; |
% plocha dolniho lichobeznika platna |
PP=D*W/2; |
% plocha trojuhelnika v pudorysu |
Q=n*(PT+PL); |
% proc? |
P=n*PP; |
% pokud nevis, udelej si nacrtek a zacni znova krokovat |
|
|
|
|
Příklad 3A.3: |
|
|
Sestavte funkci na výpočet vzdálenosti dvou bodů na zeměkouli.
Instrukce: Úlohu je třeba dekomponovat do tří funkcí. První z nich
slouží k výpočtu vzdálenosti dvou bodů na jednotkové kouli.
Přitom je použit téměř 400 let starý Napierův vzorec, který není triviální
odvodit. Druhá funkce slouží k převodu kladných i záporných úhlů z
vyjádření ve stupních, minutách a vteřinách na necelé stupně. Konečně
třetí funkce zúročí naše snažení a vyvoláním předchozích dvou
funkcí zajistí výsledek.
|
|
|
Řešení: |
|
|
function d=Napier(bod1, bod2) |
% Nejkratsi vzdalenost dvou
bodu na jednotkove kouli dle Napiera |
% d=Napier(bod1, bod2); |
% d ... vzdalenost bodu na kouli |
% bod1 ... poloha prvniho bodu
jako vektor [delka sirka] ve stupnich |
% bod2 ... poloha druheho bodu
jako vektor [delka sirka] ve stupnich |
% prevod na radiany |
bod1=bod1*pi/180; bod2=bod2*pi/180; |
% vytazeni z vektoru |
l1=bod1(1); w1=bod1(2); l2=bod2(1); w2=bod2(2); |
% Napier v 17. stoleti |
cose=sin(w1)*sin(w2)+cos(w1)*cos(w2)*cos(l1-l2); |
d=acos(cose); |
% zjisteni vzdalenosti na jednotkove kouli |
|
function phi=Uhel(dms) |
% Prevod uhlu ze stupnu, minut a vterin na necele stupne |
% phi=Uhel(dms); |
% phi ... vysledny uhel ve stupnich |
% dms ... uhel jako vektor [d m s], kde |
% d ... cele uhlove stupne |
% m ... cele uhlove minuty |
% s ... uhlove vteriny |
d=dms(1);m=dms(2);s=dms(3); |
% vydolovani informaci z vektoru |
z=sign(d); |
% urceni znamenka vysledku |
z=z+(z==0)*sign(m); |
% chybi-li stupne |
z=z+(z==0)*sign(s); |
% chybi-li minuty |
d=floor(abs(d)); |
% proc asi? |
m=floor(abs(m)); |
% jeste jednou |
s=abs(s); |
% konec spinave prace |
phi=d+m/60+s/3600; |
% proc je to az tady? |
phi=z*phi; |
% bonbonek na vrcholu dortu |
|
function [d]=Geoid(delka1,sirka1,delka2,sirka2) |
% Nejkratsi vzdalenost dvou mist na zemekouli |
% [d]=Geoid(delka1,sirka1,delka2,sirka2); |
% d ... vzdalenost v metrech |
% delka1 ... zemepisna delka 1. bodu jako vektor |
% |
[stupne minuty vteriny] |
% sirka1 ... zemepisna sirka 1. bodu jako vektor |
% |
[stupne minuty vteriny] |
% delka2 ... zemepisna delka 2. bodu jako vektor |
% |
[stupne minuty vteriny] |
% sirka2 ... zemepisna sirka 2. bodu jako vektor |
% |
[stupne minuty vteriny] |
d1=Uhel(delka1);s1=Uhel(sirka1); |
prevody |
d2=Uhel(delka2);s2=Uhel(sirka2); |
d=6386000*Napier([d1 s1],[d2 s2]); |
|
|
|
|
Příklad 3A.4: |
|
|
Od funkce k formuli pro výpočet měrného tepla dvouatomového plynu.
Instrukce: Nastudujte funkci CpIdeal2, spusťte ji pro chlorovodík
a různé teploty, nakreslete graf Cp pro teplotu od 0 do 500 stupňů
Celsia a napište matematickou formuli pro Cp jako jeden celek.
Dále sestavte funkci, která zjistí, o kolik procent se zvětší Cp
při zdvojnásobení teploty. Následuje výpis funkce:
|
|
|
Řešení: |
|
|
function [Cp]=CpIdeal2(ni,t) |
% Molarni teplo Cp pro dvouatomovou molekulu |
% podle statisticke termodynamiky |
% [Cp]=CpIdeal2(ni,t); |
% Cp ... molarni teplo pri konstantnim tlaku (J/kmol/K) |
% ni ... frekvence vibraci (8.67e13 Hz pro HCl) |
R=8314.3; |
% plynova konstanta (J/kmol/K) |
h=0.66262e-33; |
% Planckova konstanta (J/s) |
k=1.3806e-23; |
% Boltzmanova konstanta (J/K) |
T=t+273.15; |
% absolutni teplota |
x=h*ni/k./T; |
% pomocna promenna |
Cp=7/2*R+R*x.^2.*exp(x)./(exp(x)-1).^2; |
|
|
|
|
Příklad 3A.5: |
|
|
Sestavte program na výpočet přepony trojúhelníka Pythagorovou
větou (bez funkčního podprogramu).
|
|
|
Řešení: |
|
|
% Pythagorova veta |
% procviceni prikazu input |
a = input('zadej a: '); |
b = input('zadej b: '); |
c = sqrt(a^2+b^2); |
|
|
|
|
Příklad 3A.6: |
|
|
Modifikujte příklad 3A.5 a výpočet proveďte za pomoci funkčního
podprogramu.
|
|
|
Řešení: |
|
|
% Hlavni program |
% data |
a = input('zadej a: '); |
b = input('zadej b: '); |
% volani funkce |
c = prepona(a,b) |
|
function c=prepona(a,b) |
% funkce pro vypocet prepony pomoci Pythagorovy vety |
c = sqrt(a^2+b^2); |
|
|
|
|
Příklad 3A.7: |
|
|
V hlavním programu jsou zadány velikosti hran kvádru. Pomocí
funkčního podprogramu spočtěte objem, povrch a tělesovou úhlopříčku.
|
|
|
Řešení: |
|
|
% Vypocet teles |
% Hlavni program |
clear all |
a = input('zadej a: '); |
b = input('zadej b: '); |
c = input('zadej c: '); |
[V,S,u] = kvadr(a,b,c); |
|
function [V,S,u]=kvadr(a,b,c) |
% Vypocet objemu, povrchu a telesove uhlopricky |
% a, b, c ..... zadane hrany kvadru |
% V, S, u ..... objem, povrch, teles. uhlopricka |
V = a*b*c; |
S = 2*(a*b+a*c+b*c); |
u = sqrt(a^2+b^2+c^2); |
|
|
|
|
Příklady pro samostatné vypracování |
|
|
Příklad 3B.1: |
|
|
Nastudujte Heronův vzorec
a sestavte příslušnou funkci pro výpočet plochy trojúhelníka.
V čem tkví nebezpečí Heronova vzorce a jak ho odstranit?
Pak funkci Heron použijte k sestavení funkce pro plochu nepravidelného
čtyřúhelníka o známých stranách a, b, c, d, kde úhlopříčka e=AC
je rovněž známa. Funkci použijte k určení plochy reálné zahrady,
reálné místnosti nebo alespoň ideálního stolu o rozměrech 3x4 metry.
|
|
|
|
Příklad 3B.2: |
|
|
Pomocí porovnání Heronova
vzorce a ještě jednoho vzorce pro plochu trojúhelníka (kterého asi)
je možné leteckým snímkováním určit hloubku nepřístupného vodního
toku. Stačí z letadla hodit kovové neplovoucí závaží, ke kterému jsou
pevně připojeny dvě nezávislé plovoucí bóje pomocí dvou lanek
nestejné, ale známé délky. Je-li hloubka toku menší nebo rovna
délce kratšího lanka, pak se po chvíli dostanou obě bójky do
ustálené polohy na hladině. Leteckým snímkováním lze pak snadno
určit vzdálenost bójek. Vytvořte funkci Bojka s vhodným počtem
parametrů, která bude vhodnou pro určování hloubky toku. Proč se
takto nedá měřit hloubka nepřístupných rybníků a jezer?
|
|
|
|
Příklad 3B.3: |
|
|
Vypočtěte délku
zkřížené řemenice, délku řemenice kolem tří kol.
|
|
|
|
Příklad 3B.4: |
|
|
Otestujte příklad 3A.2
pro n=1000000, jiný typ stanu s obdélníky a trojúhelníky
místo lichoběžníků, objem stanu, přepis do matematického zápisu.
|
|
|
|
Příklad 3B.5: |
|
|
Přepracujte funkci
Geoid tak, aby byla schopná komunikace s předchozími
upravenými funkcemi a zjistěte přesnou vzdálenost
mezi budovou A VŠCHT Praha a vaším bydlištěm.
|
|
|
|
Příklad 3B.6: |
|
|
Souřadnice bodů uvažujte
jako čtyři parametry v radiánech a přepracujte funkci Napier.
|
|
|
|
Příklad 3B.7: |
|
|
Přepracujte funkci Uhel
tak, aby ze tří parametrů určila úhel v radiánech.
|
|
|
|
Příklad 3B.8: |
|
|
V hlavním programu je dán poloměr
podstavy válce a jeho výška. Pomocí funkčního podprogramu spočtěte
jeho objem a povrch.
|
|
|
|
Příklad 3B.9: |
|
|
V hlavním programu je dán
poloměr koule. Pomocí funkčního podprogramu spočtěte její objem a povrch.
|
|
|
|
Příklad 3B.10: |
|
|
V hlavním programu jsou dána reálná čísla
a, b, c (číslo a musí být nenulové). Pomocí funkčního podprogramu spočtěte
řešení kvadratické rovnice dané předpisem ax2+bx+c=0.
|
|
|
|
Seznam použitých příkazů |
|
|
lookfor, function, input
Editor, Debug, F10, F11, F12, průzkum pomocí myši
|
|
|
|
|