prozedura etiketadun mezuak erakusten. Erakutsi mezu guztiak
prozedura etiketadun mezuak erakusten. Erakutsi mezu guztiak

2024(e)ko otsailaren 28(a), asteazkena

15. Ariketa: azpiprogramak (III)

ZER DAKIDAN:
Ariketa bati dagokion kodifikazioa programa monolitiko batean idazteko gai naiz eta programa moduluetan zatitzeko gai naiz.



ZER IKASIKO DUDAN:
Programa bat zatitzen ikasiko dut moduluak sortuz, modulu horiek azpiprogramak deitzen dira eta bi motatakoak izan daitezke: funtzioak edo prozedurak. Ikas dezagun noiz erabili funtzioa eta noiz prozedura.




ESKATZEN DEN PROGRAMA

Zirkunzentro: Poligono batera zirkunskribatua dagoen zirkunferentziaren zentroa. Poligonoa triangelua bada, hiru erdibitzaileek elkar ebakitzen duten puntua da zirkunzentroa.

Triangeluaren zirkunzentroa eta zirkunferentzia zirkunskribatua

Triangeluaren zirkunzentroa non kokatzen den triangeluak dituen angeluen araberakoa da. Horrela, triangelu angeluzuzena bada zirkunzentroa triangeluaren hipotenusaren gainean kokatzen da, baina angelu kamutsa badu zirkunzentroa triangelutik kanpo geratzen da eta triangeluaren barruan angelu zorrotzak baditu.

Zirkunzentroaren kokapena triangeluarekiko

   TRIANGELUAREN HIRU ERPINAK:
  • A puntua eta B puntua segmentu horizontal batean daude    
  • A puntua eta B puntua ez dira bat
  • C puntua ez dago AB segmentu horizontalean
  • AC segmentua ez da bertikala
  • BC segmentua ez da bertikala

Goiko baldintzak betetzen dituzten triangeluaren hiru erpinen rAx, rAy, rBx, rBy, rCx eta rCy koordenatuak datutzat emanik, zirkunferentzia zirkunskribatuaren rR erradioa kalkulatu ondoko formula erabiliz:
Non a, b eta c triangeluaren aldeak diren eta S azalera den

Horregatik, triangeluaren rA, rB eta rC aldeen luzerak eta rS azalera kalkulatu behar dira. Aldeak lortzeko pitagoras aplikatuko dugu funtzio baten bitartez, eta S azalera eskuratzeko ondoko formula barneratzen duen funtzioa idatziko dugu:

S = 1/2(rAx·rBy + rBx·rCy + rCx·rAy - rCx·rBy - rBx·rAy - rAx·rCy)

Zirkunferentziaren erradioa zehaztu ondoren, zirkunferentziaren Z zentroa kalkulatuko dugu, hots, rZx eta rZy koordenatuak kalkulatuko ditugu. Horretarako, komenigarria izango da 3. astea | triangeluaren azalera ariketa birpasatzea, non zuzen bat adierazteko malda-desplazamendua bikotea erabiltzen den. Dagokigun ariketa honetan AC eta BC segmentuen maldak eta desplazamenduak eskuratzen dira, eta horiei esker AC eta BC segmentu biren ebakidura (rZx, rZy) puntuaren koordenatuak kalkulatzen dira.
Irudiko P puntua, ariketa honetan bilatzen den Z zentroa litzateke

Zirkunferentziaren erradioa eta zentroa ezagunak direla, frogatzerik dago zirkunferentzia horrek triangelua zirkunskribatzen duen, horretarako hiru erpinek zirkunferentziaren formula bete beharko dute. Hauxe da ariketaren programa nagusia eta azpiprogramen goiburuak:
{ 15. ariketa: A, B eta C erpinez triangelua definitu (6 koordenatu). }

{     AB aldea horizontala izango da eta ABC triangeluari dagokion    }
{     zirkunferentzia zirkunskribatuaren R erradioa kalkulatu.        }
{     ABC triangeluari dagokion zirkunferentzia zirkunskribatuaren Z  }
{     zentroaren bi koordenatuak Zx eta Zy kalkulatu.                 }

{     Datuak hiru erpinen koordenatuak dira eta prozedura batean      }
{     hartzen dira, adibidez: (0.0, 0.0), (4.0, 0.0) eta (2.0, 2.0)   }
      
program Ariketa__15 ;

{ Eskatzen diren azpiprogramak hemen idatzi:           }

{   - ErpinakEskuratu                  prozedura (irteerako 6 parametro)    }
{   - fnrAldeaLortu                     funtzioa (sarrerako 4 parametro)    }
{   - fnrAzaleraLortu                   funtzioa (sarrerako 6 parametro)    }
{   - fnrErradioaLortu                  funtzioa (sarrerako 4 parametro)    }
{   - fnrZuzenarenMalda                 funtzioa (sarrerako 4 parametro)    }
{   - SegmentuarenErdia                prozedura (sarrerako 4 parametro,    }
{                                                 irteerako 2 parametro)    }
{   - ZentroaKalkulatu                 prozedura (sarrerako 4 parametro,    }
{                                                 irteerako 2 parametro)    }
{   - fnboErpinaZirkunferentzianDago    funtzioa (sarrerako 5 parametro)    }

{ ---------------------------Programaren Nagusia--------------------------- }    
                             
var
   rAx, rAy, rBx, rBy, rCx, rCy, rZx, rZy : real ;        { koordenatuak }
   rErdiaACx, rErdiaACy, rErdiaBCx, rErdiaBCy  : real ;   { koordenatuak }
   rA, rB, rC, rR : real ;                                { distantziak }
   rS : real ;                                            { azalera }
   rMaldaAC, rPerpendikularraAC : real ;                  { maldak }
   rMaldaBC, rPerpendikularraBC : real ;                  { maldak }
   rDesplazamendu1 : real ;                               { distantzia }
   rDesplazamendu2 : real ;                               { distantzia }
begin
   writeln ;
   writeln ;
   writeln ;
   writeln ;
   
   { triangeluaren hiru erpinak irakurri }
   ErpinakEskuratu(rAx, rAy, rBx, rBy, rCx, rCy) ;
   
   writeln ; 
   
   { triangeluaren hiru aldeak lortu }
   rA := fnrAldeaLortu(rBx, rBy, rCx, rCy) ;   { BC segmentuaren luzera lortu }
   rB := fnrAldeaLortu(rAx, rAy, rCx, rCy) ;   { AC segmentuaren luzera lortu }
   rC := fnrAldeaLortu(rAx, rAy, rBx, rBy) ;   { AB segmentuaren luzera lortu }
      
   writeln('   BC aldea, rA = ', rA:0:2, ' m') ;   { BC aldearen luzera erakutsi }
   writeln('   AC aldea, rB = ', rB:0:2, ' m') ;   { AC aldearen luzera erakutsi }
   writeln('   AB aldea, rC = ', rC:0:2, ' m') ;   { AB aldearen luzera erakutsi }
   
   { triangeluaren azalera kalkulatu erpinak ezagunak izatean }
   rS := fnrAzaleraLortu(rAx, rAy, rBx, rBy, rCx, rCy) ;
    
   writeln('   rS azal. = ', rS:0:3, ' m^2') ;
   writeln ;
   
   { erradioa kalkulatzeko formula: (rA·rB·rC)/(4·rS) }
   rR := fnrErradioaLortu(rA, rB, rC, rS) ; 

   writeln('   rR erra. = ', rR:0:3, ' m') ;
   writeln ;   
   
   { AC perpendikularraren malda } 
   rMaldaAC := fnrZuzenarenMalda(rAx, rAy, rCx, rCy) ;
   writeln('   AC malda = ', rMaldaAC:0:2) ;
   rPerpendikularraAC := -(1/rMaldaAC) ;
   writeln('   AC perp. = ', rPerpendikularraAC:0:2) ;
   
   { AC perpendikularren zuzenak duen desplazamendua } 
   SegmentuarenErdia(rAx, rAy, rCx, rCy, rErdiaACx, rErdiaACy) ;                 
   writeln('   AC erdia = (', rErdiaACx:0:2, ', ', rErdiaACy:0:2, ')') ;     
   rDesplazamendu1 := rErdiaACy + rErdiaACx/rMaldaAC ;
   writeln('   Desplaz1 = ', rDesplazamendu1:0:2, ' m') ;
   writeln ;

   { BC perpendikularraren malda }
   rMaldaBC := fnrZuzenarenMalda(rBx, rBy, rCx, rCy) ;
   writeln('   BC malda = ', rMaldaBC:0:2) ;
   rPerpendikularraBC := -(1/rMaldaBC) ;
   writeln('   BC perp. = ', rPerpendikularraBC:0:2) ;
   
   { BC perpendikularren zuzenak duen desplazamendua }
   SegmentuarenErdia(rBx, rBy, rCx, rCy, rErdiaBCx, rErdiaBCy) ;       
   writeln('   BC erdia = (', rErdiaBCx:0:2, ', ', rErdiaBCy:0:2, ')') ;
   rDesplazamendu2 := rErdiaBCy + rErdiaBCx/rMaldaBC ;
   writeln('   Desplaz2 = ', rDesplazamendu2:0:2, ' m') ;
   writeln ;   
   
   { Zentroa bi zuzen perpendikularren arteko ebakidura izango da } 
   { Zuzen z1:   m1 = rPerpendikularraAC | d1 = rDesplazamendu1   }
   { Zuzen z2:   m2 = rPerpendikularraBC | d2 = rDesplazamendu2   }

   { Zuzen z1:   rZy = m1·rZx + d1      }
   { Zuzen z2:   rZy = m2·rZx + d2      }
   
   { m1·rZx + d1 = m2·rZx + d2  ==>  rZx = (d1 - d2) / (-m1 + m2)          }
   {         rZy = m1·rZx + d1  ==>  rZy = m1·(d1 - d2) / (-m1 + m2) + d1  }
   
   { rZx = (d1 - d2) / (-m1 + m2)       }
   { rZy = (m2·d1 - m1·d2) / (-m1 + m2) }
   
   ZentroaKalkulatu(rPerpendikularraAC, rPerpendikularraBC, rDesplazamendu1, rDesplazamendu2, rZx, rZy) ;
  
   writeln('   Z zentr. = (', rZx:0:2, ', ', rZy:0:2, ')') ;
   writeln ;
   writeln ;
        
   writeln('   (x - rZx)^2 + (y - rZy)^2 - rR^2  <  0.000001') ;
   
   if fnboErpinaZirkunferentzianDago(rZx, rZy, rR, rAx, rAy) then
      writeln('   (', rAx:0:2, ', ', rAy:0:2, ') erpina zirkunferentzian dago')
   else
      writeln('   Errorea A erpinean') ;
   if fnboErpinaZirkunferentzianDago(rZx, rZy, rR, rBx, rBy) then
      writeln('   (', rBx:0:2, ', ', rBy:0:2, ') erpina zirkunferentzian dago')
   else
      writeln('   Errorea B erpinean') ;
   if fnboErpinaZirkunferentzianDago(rZx, rZy, rR, rCx, rCy) then
      writeln('   (', rCx:0:2, ', ', rCy:0:2, ') erpina zirkunferentzian dago')
   else
      writeln('   Errorea C erpinean') ;
         
   writeln ;
   readln ;
end.            { Programaren amaiera }

Programaren balizko exekuzio bat hurrrengo irudian erakusten da:






  •  Emaitza laster... 

 

14. Ariketa: azpiprogramak (II)

ZER DAKIDAN:
Menu bat programa batean nola egiten den badakit.



ZER IKASIKO DUDAN:
Menu bat funtzio batean kodetu eta programa nagusitik deiak egiten ikasiko dut.


Ariketa hauek gogora ekarri eta ariketa guztiak programa bakar batean bildu:

Programa berria modulutan antolatzeko funtzioak eta prozedurak erabili. Programa berriaren exekuzioa gidatzeko menu honetaz baliatu:
   ====================================Menua====================================
     A  Mendi baten altuera emanik zeruertzaren distantzia lortu
     B  Dado bat 5 aldiz jaurti ondoren balio minimoa eta maximoa pantailaratu
     C  Koordenatuak formatuz aldatu: Hirurogeitatarretik dezimalera
     D  Koordenatuak formatuz aldatu: Dezimaletik hirurogeitatarrera
      
     I  Programatik irten
   =============================================================================

Baina, menu horren aukeraren hautapena funtzio batean egin dadila. Hau da, programa nagusian fncMenua funzioari deia egingo zaio, eta fncMenua funtzio barruan aukeren deskribapenak erakutsi ondoren, erabiltzailaren hautapena teklatuz jasoko da eta balio hori funtzioak programa nagusiari itzuliko dio.

Programa nagusiak itxura hau izango du:
      begin
        repeat
           cAukera := fncMenua ;

           case cAukera of
              'A': begin
                      (* A  Mendi baten altuera eman eta zeruertzaren distantzia lortu *)
                   end ;
              'B': begin
                      (* B  Dado bat 5 aldiz jaurti ondoren balio minimoa eta maximoa pantailaratu *)
                   end ;
              'C': begin
                      (* C  Koordenatuak formatuz aldatu: Hirurogeitatarretik dezimalera *)
                   end ;
              'D': begin
                      (* D  Koordenatuak formatuz aldatu: Dezimaletik hirurogeitatarrera *)
                   end ;
           end ;

           if cAukera <> 'I' then
           begin
              cItxaron := readkey ;
              writeln(cItxaron) ;
           end ;

           clrscr ;
        until cAukera = 'I' ;
      end.

Hona hemen programaren balizko exekuzio bat:








 

13. Ariketa: azpiprogramak (I)




Leonardo Pisano (Pisa, Italia, 1170-1250), Leonardo Bonacci, Leonardo Fibonacci edo Fibonacci moduan ezaguna, Italiar matematikaria izan zen, Erdi Aroko ezagunetarikoa. Ezaguna da batez ere bi aurkikuntzengatik:

  • Hindu-arabiar zenbaki sistema Europan sartu zuen eta berau erabiltzeko bideak jarri zituen XIII. mendeko "Liber Abaci" liburuaren bitartez
  • Fibonacciren zenbakiak deskribatu zituen liburu berean, nahiz eta berak ez zituen aurkitu baizik eta adibide moduan jarri
Leonardo Pisano, Fibonacci, ezagutzeko hemen duzu artikulu bat Fibonacci, el matemático que se puso a contar conejos y descubrió la secuencia divina.


Fibonacciren sekuentziako lehen zenbakia 0 da, Fibonacci-ren bigarren zenbakia 1 da, eta hirugarren zenbakia lortzeko aurreko biak batuko dira, horregatik Fibonacciren hirugarren zenbakia 1 da, laugarren zenbakia 2 izango da, bosgarrena 3, ... 
Beraz, Fibonacciren sekuentzia honako hau da:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...

Fibonacciren zenbakiak grafikoki adieraztean honako blokeen sorta eta espirala lortzen dira:




Fibonacciren sekuentziako bi zenbaki hartuz eta zatiketa eginez, urrezko zenbakia edo jainkozko proportzioa edo urrezko proportzioa edo zerutiar zenbakia lortzen da:

Fibonacciren sekuentzia sarritan agertzen da naturan. Izan ere, naturan hazkundea gertatzen denean Fibonacciren sekuentziaren arabera ematen da:

     

     

     







Eskatzen den programa (prozedura bat eta funtzio bat)

Programa bakarra izan arren programak bi zati izango ditu. Lehen zatian prozedura bati dei egingo zaio eta programaren bigarren zatian funtzio bati dei egingo zaio.

Programaren prozedura eta programaren funtzioa jarraian deskribatzen dira eta bakoitzaren kode gehiena ematen da. Ikaslearen lana da kodeak bukatzea eta programaren emaitzak ulertzea.



Lehen zatia. Fibonacciren sekuentzia osatuko duten zenbakien iZenbat kopurua teklatuz irakurri programa nagusian eta prozedura batek ondoko taularen pantailaraketa egin dezala FOR-DO egitura bat erabiliz, FibonaccirenSekuentziaPantailaratu izeneko prozeduraren barruan errepikatzen den prozesua hau delarik:
   procedure FibonaccirenSekuentziaPantailaratu(iZenbat: integer) ;

      ...
   
   begin { prozeduraren kodea hemen hasten da }

      ...
      
      for k:=3 to iZenbat do
      begin
         iFibo3 := iFibo1 + iFibo2 ;
         iIndizea := iIndizea + 1 ;
         writeln(iIndizea:15, iFibo3:15, 1.0*iFibo3/iFibo2:25:7) ;
      
         iFibo1 := iFibo2 ;
         iFibo2 := iFibo3 ;
      end ; 

      ...
      
   end ; { prozeduraren kodea hemen amaitzen da }      

Programaren lehen zatiko irteera bat hau izan daiteke:




Bigarren zatia. Prozesu errepikakor bat izango da eta bertatik irteteko b edo B erantzun beharko da, bestela programa nagusian iMuga teklatuz irakurriko da eta funtzio batek kalkulatuko du 0-tik hasita zenbat Fibonacciren zenbaki dauden. Horretarako, WHILE-DO egitura bat erabiliko da, funtzio barruko prozesu errepikakorra hauxe da, non funtzioak itzuli behar duen emaitza iFiboKopuru den eta arrazoi horregatik balio hori kanporatu behar du fniFibonacciZenbakienKopuruaKalkulatu izeneko funtzioak:
   function fniFibonacciZenbakienKopuruaKalkulatu(iMuga: integer): integer ;

      ...
   
   begin { funtzioaren kodea hemen hasten da }

      ...
      
      iFibo1 := 0 ;
      iFibo2 := 1 ;
      iFibo3 := iFibo1 + iFibo2 ;

      while iFibo3 <= iMuga do
      begin
         iFibo1 := iFibo2 ;
         iFibo2 := iFibo3 ;
         iFibo3 := iFibo1 + iFibo2 ;
         iFiboKopuru := iFiboKopuru + 1 ;
      end ;
   
      fniFibonacciZenbakienKopuruaKalkulatu := iFiboKopuru ;
   end ; { funtzioaren kodea hemen amaitzen da }

Programaren bigarren zatiko irteera bat hau izan daiteke: