| Programacion | Pac 2 - Madel Ortiz (comentada)

Pac 2 2011/12-2 de Madel Ortiz comentada por el consultor Jaume Gil. Calificación: B
View more...
   EMBED

Share

Preview only show first 6 pages with water mark for full document please download

Transcript

Estudis d’Informàtica, Multimèdia i Telecomunicació Programació PAC2 — Segona Prova d'Avaluació Continuada Nom: Maria del Mar Ortiz Valor Indicacions generals: Raoneu i justifiqueu totes les respostes. Les respostes incorrectes no disminueixen la nota. Per a dubtes i aclariments sobre l’enunciat, adreceu-vos al consultor responsable de l’aula. Lliurament: 1. S'ha de respondre les preguntes al mateix document de l'enunciat que rebrà el nom CognomsNomP_PAC2.doc (o CognomsNomP_PAC2.odt) 2. La codificació de les preguntes 6 i 7 es lliurarà mitjançant els fitxers PAC2_exer06.php i PAC2_exer07.php que es construiran sobre les plantilles adjuntes. És especialment important respectar el nom de lliurament d'aquests arxius php. 3. Els dos fitxers es comprimiran en un únic arxiu de format zip o rar de nom CognomsNomP_PAC2.zip (o CognomsNomP_PAC2.rar) que es lliurarà a la bústia de "Lliurament i registre d'AC" 4. Data límit per lliurar la solució: dilluns, 4 d'abril de 2012 (a les 23:59 hores). És imprescindible respectar el format i data d’entrega. La no adequació a aquestes especificacions pot suposar la no avaluació de la PAC. 1 Exercici 1: Declaració d’accions i funcions [10%] Objectius: Distingir entre accions i funcions. Declarar accions i funcions per a resoldre un problema. Definir els paràmetres, amb els tipus de dades corresponents i els modificadors d’entrada i sortida correctes. Materials: M1 i M2 Tasca: Per a cada apartat, decidiu si és millor una acció o una funció i definiu-ne la capçalera (només es demana la capçalera, no cal que dissenyeu cap algorisme). Es demana la capçalera d'un mòdul (acció o funció) que: [recordeu que podeu fer servir el tipus text que conté una cadena de caracters] a) Que rebi una data en format dd-mm-aaaa i digui si és una data correcta o incorrecta (p.e. si rebés 31-2-2010 hauria de dir incorrecte) Faria servir una funció, l’acció comprovarà els valors de dd, mm i aaaa i si son correctes escriurà “correcta” i si no ho son escriurà “incorrecta” funció validacioData(data: text) : booleà Correcte b) Que rebi una data en format dd-mm-aaaa i digui si és una data correcta o incorrecta i, a més retorni el dia, el mes i l'any en format numèric. Faria servir una funció, com en el cas anterior a més de comprovar els valors de dd, mm i aaaa i si son correctes escriure “correcta” i si no ho son escriure “incorrecta”, i escriurà el dia, mes i any en format numèric. funcio validacioData(data: text): text s'ha de retornar tres números, dia, mes i any c) Donats l'aigua ploguda en una tempesta que arribarà a un embassament, la capacitat màxima d'un embassament i el volum d'aigua emmagatzemada, digui la quantitat d'aigua que s'ha de desguassar per evitar que es desbordi. Faria servir una funció ja que l’efecte d’aquesta es retornar un valor. funcio desguassar( Lplutja : real, Lmax : real, Lembassament : real): real ; Correcte d) Donat el codi numèric del producte, el preu unitari i la quantitat que es desitja, indiqui si hi ha prou unitats en stock i el cost total de la venda. funcio calcularTotal( codi : enter, preu : real, quantitat : enter): real; i on etr diu si n'hi ha en stock o no? 2 Exercici 2: Especificació d’accions i funcions [10%] Objectius: Descriure de manera precisa què fa una funció o una acció sense necessitat de saber com ho fa. Materials: M1 i M2 Tasca: Especifiqueu les funcions i/o accions dels apartats b i c de lʼexercici 1. Cal que indiqueu la precondició, la postcondició i, si es tracta dʼuna funció, què retorna. b) { Pre: dd = DD i DD ≥ 1 i DD ≤ 31 i mm = MM i MM ≥ 1 i MM ≤ 12 i aaaa = AAAA i AAAA > 0 i AAAA < 9999 } funció validacioData( entsor data: text) : text En realitat faria que comprove si per als mesos 1, 3, 5, 7, 8, 10 i 12 dd esta entre 1 i 31, per al mes 2 si dd es igual a 28, i si per als mesos 4, 6, 9 i 11 si dd esta entre 1 30. Si no es compleixen totes aquestes comprobacions ( i les del pre escriurà el text “La data no es correcta” Si es compleixen totes aquestes comprobacions escriurà el text “La data es correcta”. Retorna la data en format numèric. { Post: data = DD-MM-AAAA } fa exactament el contrari que diu l'enunciat c) { Pre: Lplutja = LPLUTJA i Lmax = LMAX i Lembassament = LEMBASSAMENT } funcio desguassar( Lplutja : real, Lmax : real, Lembassament : real): real ; { Post: Ldesguassar = (LPLUTJA + LEMBASSAMENT) – LMAX } Correcte 3 Exercici 3: Modificadors d’entrada i sortida [15%] Objectius: Saber detectar la correctesa en la crida a accions o funcions, entenent el funcionament dels modificadors d’entrada i sortida dels paràmetres. Materials: M1 i M2 Tasca: Donats lʼalgorisme i les capçaleres de les següents accions i funcions: funcio function1( x: enter, y: enter, z: real) : enter; funcio function2( x: enter, c: caracter, b: boolea) :real; accio action1( ent x: enter, entsor z: enter) ; accio action2( ent c: caracter, sor x: enter, entsor y: enter); algorisme algorithm var i, j, k: enter; x, y, z : real; d : caracter; b: boolea; fvar x := 5.0; y := 10.1; i := 0; d := readChar(); b := fals; ... writeInteger (i + j); writeRea l(x / 2.0); writeChar (d); b := (x + y) = (c / 2.0); si (b) llavors writeChar(‘S’); sino writeChar(‘N’); fsi falgorisme 4 Responeu a cada apartat si és correcte o no substituir el requadre gris de l’algorisme algorithm per la instrucció que es dóna i, si no ho és, indiqueu-ne les causes. a) action2 (d, function1(3, i, y ), k); Aquest cas es incorrecte perque, tot i que la function 1 es corrècta ens dona com a resultat un enter, però a l’action 2 aquest paràmetre son es de sortida aixì que no pot rebre el valor que retorna la function 1 Correcte b) action1 (function1(x, y), z); Aquesta instrucció també es incorrecta ja que, per començar a la function 1 li falta un paràmetre, però els dos que té (x i z) deuirien de ser enters i son reals. Correcte c) x := function1 (function1(i, i, y), 5, function2(k, 'x', b)); Aquesta instrucció també es incorrecta ja que el resultat final d’evaluar les tres funcions ens retorna un enter, i en aquest cas x es un real Correcte d) x := function2 (action1 (1, j), d, true); Aquesta instrucció si que es corrècta ja que el resultat de la function 2 es un real i x es un real. Aleshores seguiriem analitzant l’algorisme que tot va donant correcte, però en l’expressió: b := (x + y) = (c / 2.0); trobem que no tenim definida la variable c. només has de comentar la intrucció del requadre, que és incorrecta 5 Exercici 4: Disseny d’algorismes [15%] Objectius: Entendre un algorisme i saber fer crides a accions i funcions. Materials: M1 i M2 Tasca:En un jutjat disposen d'un algorisme per triar advocat d'ofici per als judicis. Llegeix del canal estàndard el nom de l'advocat (text), el tipus de judici ( un caràcter 'p', 'c' o 'f' segons sigui un judici penal, civil o de familia) i un tercer caràcter que indica la sala on es realitzarà el judici (el jutjat disposa de les sales 'A' a la 'K'). L'algorisme al final escriu: • 'S' si es rebutja l'advocat perquè no correspon en especialitat • 'H' si es rebutja l'advocat perquè està rebutjat a la sala en què es realitzarà el judici • 'E' si es rebutja perquè la seva mitjana d'èxits està per sota de la mitjana general dels jutjats • ’Y' altrament. Ompliu les caixes, amb una única instrucció o expressió a cada una, per aconseguir el comportament que us hem descrit. Lʼalgorisme resultant ha dʼutilitzar obligatòriament les següents accions i funcions, que no heu dʼimplementar: Acció que llegeix del canal d’entrada estàndard la informació d'advocat i judici: accio getInfo (sor attorney: text, sor trial: caracter, sor hall: caracter); Acció que donat el nom d'un advocat retorna la seva especialitat i una cadena de text on estan totes les sales on no pot actuar: accio getAttorneyInfo (ent name: text, sor specialty: caracter, sor forbiddenHall: text); Funcio que rep una sala i una llista de sales i retorna cert si la sala està en la llista: funció hallInForbidden ( hall: caracter, forbidden: text): booleà; Funcio que rep el nom d'un advocat i retorna la seva mitjana d'èxits: funció getAttorneySuccess (attorney: text): real; Funcio que retorna la mitjana d'èxits general del jutjat: funció getMeanSuccess (): real; 6 algorisme chooseAttorney const SPECIALTY : caracter = ‘S’; HALL : caracter = ‘H’; EFFICIENCY : caracter = ‘E’; YES : caracter = ‘Y’; fconst var attName, forbiddenList : text; trialType, hall, attSpecialty : caracter; okSpecialty, okHall, okEfficiency: booleà; fvar {Llegeix del canal d’entrada estàndard la informació de l'advocat i judici que hem de tractar} accio getInfo (sor attorney: text, sor trial: caracter, sor hall: caracter); ; {obté les dades de l'advocat} accio getAttorneyInfo (ent name: text, sor specialty: caracter, sor forbiddenHall: text); ; {calcula idoneitats pel judici} okSpecialty := trialType = attSpecialty; funció hallInForbidden ( hall: caracter, forbidden: text): booleà okHall := okEfficiency:= ; funció getMeanSuccess (funció getAttorneySuccess (attorney: text): real; ): real; ; ; fer els crides no és copiar les capçaleres de les funcions si okSpecialty i okHall i okEfficiency llavors writeChar (YES) sino si no okSpecialty llavors writeChar (SPECIALTY) fsi si no okHall llavors writeChar (HALL) fsi si no okEfficiency llavors writeChar (EFFICIENCY) fsi fsi falgorisme 7 Exercici 5: Disseny d’algorismes [15%] Objectius: Dissenyar una funció/acció. Materials: M1 i M2 Tasca: Es demana un mòdul (acció o funció el més adequat) per calcular el montant total d'un rebut de l'aigua d'una urbanització. El consum d'aigua es tarifa per blocs a 0.35 €/m3 fins a 6m3, 0.70 €/m3 els següents 6m3 i 1.05 €/m3 la resta. Per altra banda, en el rebut també incorpora la taxa de clavegueram (0.15 €/m3 fins a 10m3 i 0.25 €/m3 la resta) i el cànon d'obres hidràuliques (0.30 €/m3 fins a 10m3 i 0.60 €/m3 la resta). Tots els conceptes estan gravats amb un 7% d'IVA. El mòdul ha de rebre el consum mensual d'un domicili (en m3) i retorna el total del rebut. Sent Laigua els litres d’aigua consumida, totalRebut el preu final del rebut amb el iva inclos, p el total d’euros d’aigua consumida, taxa el total d’euros de taxa de clavegueram i canon el total d’euros de canon d’obres. algorisme rebutAigua { Pre: sabent els preus segons consum de l’aigua, de la taxa de clavegueram i del canon d’obres i el consum d’aigua, Laigua = LAIGUA } accio rebutAigua ( ent Laigua : real, sor totalRebut : real ): real si no és una funció, no té tipus. Hauria de ser una funció que retornés amb un return p1 := 0.35; p2 := 0.7; p3 := 1.05; t1 := 0.15; t2 := 0.25; c1 := 0.3; c2 := 0.6; a := readReal(); si Laigua ≤ 6 llavors p := Laigua * p1; fsi si a > 6 i a < 12 llavors p := (Laigua * p1) + ((Laigua - 6) * p2); fsi 8 si Laigua > 6 i a > 12 llavors p := (Laigua * p1) + (Laigua * p2) + ((Laigua - 12) * p3); fsi si Laigua ≤ 10 llavors taxa := Laigua * t1; canon := Laigua * c1; fsi si Laigua > 10 llavors taxa := (10 * t1) + ((Laigua – 10) * t2); canon := ( 10 * c1) + ((Laigua – 10) * c2); fsi No contemp`les en cap cas un sino i hi ha força llocs on posar-los i estalviar-te condicions inútils totalRebut := (p + taxa + canon) + ((p + taxa + canon) * 0.07); falgorisme {Post: p = } Tot i que no es demana codificar l’algorisme en PHP l’he fet, ja que trobe que es la millor manera de comprovar si funciona be, i, sobretot, d’aprendre, de trobar “natural” un llenguatge que de primer cop sembla xino. I em funciona! :) PAC2_Exer05

PAC2_Exer05

***** Maria del Mar Ortiz Valor ******

"; //per anar comprovant el if ($a <= 6) { $p = ($a * $p1); } if ($a > 6 && $a < 12) { $p = (6 * $p1) + (($a - 6) * $p2); } if ($a > 6 && $a > 12) { $p = (6 * $p1) + (6 * $p2) + (($a - 12) * $p3); } print "Preu per litros consumits = $p
"; //per anar comprovant el funcionament if ($a <= 10) { $taxa = ($a * $t1); $canon = ($a * $c1); } if ($a > 10) { $taxa = (10 * $t1) + (($a - 10) * $t2); $canon = (10 * $c1) + (($a - 10) * $c2); } print "Taxa de clavegueram = $taxa
"; //per anar comprovant funcionament print "Canon = $canon
"; //per anar comprovant el funcionament $totalRebut = ($p + $taxa + $canon) + (($p + $taxa + $canon) * 0.07); } /******** PROGRAMA PRINCIPAL **********/ rebutAigua($a, &$totalRebut); print "

El preu total del rebut (iva inclos) es: $totalRebut euros

"; ?>
el 10 Exercici 6: Programació [20%] Objectius: Codificar un algorisme en llenguatge PHP. Fer proves per a veure si el funcionament és correcte. Materials: Guia bàsica de PHP i miniguies. Tasca: El següent algorisme realitza simulacions sobre l'evolució d'una població d'organismes en referència a un gen determinat del qual existeix dos al·lels A i a i en què només actua la deriva genètica (aleatòria) i una selecció contra l'al·lel A. El programa llegeix de l'entrada estàndard quatre valors: • n mida de la població (50 ≤ n ≤ 100) • p freqüència de l'al·lel A (0 ≤ p ≤ 1) • s taxa de mutació A→ a (0 ≤ s ≤ 1) • r quantitat de repeticions de la simulació (1 ≤ r ≤ 50) comprova que les dades entrades tenen valors correctes i passa a realitzar les simulacions. Per a cada simulació, escriu el número de generació i els valors de p i q. Cada simulació finalitza quan p agafa el valor 0 o el valor 1. Considereu que existeix el tipus text, la funció readText() i l'acció writeText( t: text). També disposem de l'acció writeLF() que escriu un salt de línia a la sortida estàndard. algorisme evolucio var n, r, i, fA, fa : enter; p, q, s : real; ok : booleà ; fvar { funcions i accions } acció getData( sor n : enter, sor p : real, sor s : real, sor r : enter) n := readInteger(); p := readReal(); s := readReal(); r := readInteger(); facció funció validateData (n : enter, p : real, s : real, r : enter): booleà var ok : booleà; fvar ok := cert; si n < 50 o n > 100 llavors writeText ("El nombre d'individus n ha de prendre valors entre 50 i 100"); ok := fals; fsi si p < 0.0 o p > 1.0 llavors writeText ("La freqüència de l'al·lel A (p) ha de prendre valors entre 0 i 1"); ok := fals; fsi 11 si s < 0.0 o s > 1.0 llavors writeText ("El coeficient de selecció (s) ha de prendre valors entre 0 i 1"); ok := fals; fsi si r < 1 o r > 50 llavors writeText ("(r) ha de prendre valors entre 1 i 50 "); ok := fals; fsi retorna ok; ffuncio funcio selection (s: real): enter var treshold : real; fvar treshold = s * 1000.0; si integerToReal( rand(1, 1000)) < treshold llavors retorna -1; sino retorna 0; fsi ffuncio funció generateAllele( total: enter, treshold: enter) : enter var allele: enter; fvar allele := rand (1, total); si allele > treshold llavors retorna 0; sino retorna 1; fsi ffuncio accio generation (ent nGeneration : enter; ent totalAllele : enter, entsor nA: enter, ent s : real) var Aqtty, actual, i: enter; p, q : real; fvar Aqtty := 0; per i=1 fins totalAllele fer actual := generateAllele(totalAllele, nA); si actual = 1 llavors actual := actual + selection(s); fsi Aqtty := Aqtty + actual; fper nA := Aqtty; p := integerToReal(nA) / integerToReal(totalAllele); q := 1.0 - p; writeInteger( nGeneration ); writeReal( p ); writeReal( q ); writeLF(); faccio 12 funcio simulation (nSimulation:enter, n:enter, p:real, s:real) : booleà var totalAllele, nA, nGeneration : enter; fixat : booleà; fvar totalAllele := n * 2; nA := realtoInteger ( integerToReal(totalAllele) * p ); q := 1.0 - p; nGeneration := 0; writeText ("Simulacio " ); writeInteger ( nSimulation ); writeLF(); writeText ("Generacio"); writeText ("Freq (A)"); writeText ("Freq (a)"); writeLF(); writeInteger (nGeneration); writeReal ( p ); writeReal ( q ); mentre nA ≠ 0 i nA ≠ totalAllele fer nGeneration := nGeneration + 1 ; generation ( nGeneration, totalAllele, nA, s); fmentre fixat := nA ≠ 0; writeText (" S'ha fixat l'al·lel "); si fixat llavors writeChar ( 'A'); sino writeChar ( 'a'); fsi writeLF(); retorna fixat; ffuncio { Programa principal } getData (n, p, s, r); ok := validateData (n, p, s, r); q := 1.0 - p; fA := 0; writeText (" SIMULADOR D'EVOLUCIÓ "); writeLF(); writeText ("Mida de la població: "); writeInteger (n); writeLF(); writeText ("Freqüències dels al·lels A i a : "); writeReal (p); writeReal (q); writeLF(); writeText ("Coeficient de selecció contra A: "); writeReal (s); writeLF(); 13 writeText ("Quantitat de simulacions: "); writeInteger (r); writeLF(); per i := 1 fins r fer si simulation (i, n, p, s) llavors fA := fA + 1; fsi fper fa := r - fA; writeLF(); writeText (" Resum de resultats "); writeLF(); writeText (" Quantitat de simulacions "); writeInteger ( r ); writeLF(); writeText (" Simulacions amb fixació de A: "); writeInteger (fA); writeLF(); writeText (" Simulacions amb fixació de a: "); writeInteger (fa); falgorisme Indicacions per a la traducció • L'entrada de dades es farà amb el mètode $_GET. La crida al programa ha de ser del tipus PAC2_exer06.php?n=N&p=P&s=S&r=R on n, p, s i r tenen el significat explicat a l'inici de l'enunciat • Tots els salts de línia en la impressió s'han simbolitzat en l'algorisme amb una instrucció writeLF() • En PHP existeix una function rand (int min, int max) que es comporta com la funció rand que s'empra en l'algorisme. Per exemple rand(1, 100) retorna un número aleatori entre 1 i 100. • Recordeu que en PHP no cal fer les conversions entre enters i reals • Recordeu que l'operador de comparació en PHP és el doble igual ==. L'operador = és l'operador d'assignació. • Per arrodonir el contingut d'una variable $a a una determinada quantitat de decimals es pot emprar la funció round($a, num_dec). P.e. round($a,2) arrodoniria el valor de $a al segon decimal. • Per incrementar variables en una unitat, és còmode fer servir l'operador ++. Per exemple $a++; equival a la instrucció $a = $a + 1; • Per sumar una quantitat a una variable, és còmode fer servir l'operador +=. Per exemple $a += $b; equival a $a = $a + $b; Podeu comprovar el funcionament del programa amb l'enllaç: http://comoras.uoc.edu/~jgilm/ PAC2_exer06.php?n=N&p=P&s=S&r=R 14 Enganxeu aquí el vostre llistat del fitxer PAC2_exer06.php PAC2_Exer06

PAC2_Exer06

***** Maria del Mar Ortiz Valor ******

n ha de prendre valor entre 50 i 100"); */ /******** FUNCTION **********/ 15 //AQUÍ VAN LES FUNCIONS function getData(&$n, &$p, &$s, &$r) { $n = $_GET["n"]; $p = $_GET["p"]; $s = $_GET["s"]; $r = $_GET["r"]; } // de la function function validateData($n, $p, $s, $r) { $ok = true; if (($n < 50) || ($n > 100)) { print ("El nombre d'individus n ha de prendre valor entre 50 i 100
"); $ok = false; } // del if if (($p < 0.0) || ($p > 1.0)) { print ("La freqüencia del al·lel A p ha de prendre valor entre 0 i 1
"); $ok = false; } //del if if (($s < 0.0) || ($s > 1.0)) { print ("El coeficient de seleccio (s) ha de prendre valor entre 0 i 1
"); $ok = false; } //del if if (($r < 1) || ($r > 50)) { print (" (r) ha de prendre valor entre 1 i 50
"); $ok = false; } //del if return $ok; } // de la function function selection($s) { $treshold = ($s * 1000.0); if (rand(1,1000) < $treshold) { return -1; } //del if else { return 0; } //del else } // de la function 16 function generateAllele($total, $treshold) { $allele = rand(1,$total); if ($allele > $treshold) { return 0; } //del if else { return 1; } //del else } // de la function function generation($nGeneration, $totalAllele, &$nA, $s) { $Aqtty = 0; for ($i = 1; $i <= $totalAllele; $i++) { $actual = generateAllele($totalAllele, $nA); if ($actual == 1) { $actual = $actual + selection($s); } // final del if $Aqtty = $Aqtty + $actual; }// final del for $nA = $Aqtty; $p = ($nA / $totalAllele); $q = (1.0 - $p); print "$nGeneration | "; print "$p | "; print "$q"; print "
"; } // de la function function simulation($nSimulation, $n, $p, $s) { $totalAllele = ($n * 2); $nA = ($totalAllele * $p); $q = (1.0 - $p); $nGeneration = 0; print "

Simulacio $nSimulation

"; print "Generacio | freq(A) | freq(a)
"; print "$nGeneration | $p | $q
"; 17 while (($nA != 0) && ($nA != $totalAllele)) { $nGeneration++; // o $Generation = ($nGeneration + 1); generation($nGeneration, $totalAllele, $nA, $s); } //del while $fixat = ($nA != 0); print "S'ha fixat l'al·lel "; if ($fixat) { print "'A'
"; } // del if else { print "'a'
"; } //del else return $fixat; } // de la function /******** MAIN **********/ //AQUÍ VA EL PROGRAMA PRINCIPAL getData($n, $p, $s, $r); if ($ok = validateData($n, $p, $s, $r)) { $q = (1.0 - $p); $fA = 0; print "

SIMULADOR D'EVOLUCIO


"; print "

Mida de la poblacio: $n individus
Freqüencies inicials dels al·lels: f(A): $p; f(a): $q
Coeficient de seleccio contra A: $s
Quantitat de simulacions: $r

"; // print "Abans del for
"; for ($i = 1; $i <= $r; $i++) { if (simulation($i, $n, $p, $s)) { $fA = ($fA + 1); }//del if } //del for 18 // print "dins del for, volta $i
"; $fa = print print print print print ($r - $fA); "
"; "Resum de resultats
"; "Quantitat de simulacions: $r
"; "Simulacions amb fixacio de A: $fA
"; "Simulacions amb fixacio de a: $fa
"; } //del if validate ?>
Correcte 19 Exercici 7: Codificació [15%] Objectius: Creació d’algorismes en PHP. Materials: Guia bàsica de PHP i miniguies. Tasca Crear un programa que simuli la trajectòria que seguiria una pedra llençada amb un tirador. El programa ha de rebre tres paràmetres: • vini : velocitat inicial expressada en m / s. • angle : angle respecte l'horitzontal expressat en graus • unit : si pren el valor i el programa donarà els resultat en polzades. Altrament, els resultats es donaran en metres. en esquema el programa realitza una simulació com la imatge següent Escrivint, en forma de llista (x, y), la posició de la pedra en intervals de 0.1 s. Fins que la pedra torna a tocar a terra (y pren el valor 0). Tot i semblar un problema complex de fet es tradueix a dos problemes simples, calcular la posició de la pedra en l’horitzontal i en la vertical. En l’horitzontal es tracta d’un moviment uniforme i en la vertical d’un moviment uniformement accelerat que es descriuen tot seguit. 1. Obtenció de les velocitats inicials horitzontal (vx) i vertical (vy) a partir de la velocitat inicial i l’angle. Tal com es pot veure a la imatge de la dreta la velocitat horitzontal es calcula com: vx = vini * cos (angle) i la vertical com vy = vini * sin (angle) 2. Càlcul de la posició horitzontal de l’objecte en el moment ti Aquest moviment és uniforme, per tant la posició en cada moment es calcula: posx = vx * ti 20 3. Càlcul de la posició vertical de l’objecte en el moment ti Es tracta d’un moviment que en un principi és ascendent i després descendent perquè s’oposa a la gravetat. Si denotem per G l’acceleració de la gravetat, la posició en vertical en el moment ti es calcula: posy = vy * ti - ½ G ti2 La posició vertical anirà augmentant mentre la primera part de l’equació (vy * ti) tingui un valor superior a la segona (½ G ti2), moment a partir del qual anirà disminuint. En un moment determinat posy tornarà a ser 0. Com que els càlculs que es demanen no són continus sinó a intervals de 0.1 s, és difícil que la posició 0 es recuperi en una dècima exacta. El més probable és que a la dècima ti, posy encara sigui positiu i a la dècima següent ja sigui negatiu. Agafeu aquesta primera dècima amb valor negatiu per finalitzar la simulació. Si es vol, de cara que la llista de dades sigui més “estètica” aquest primer valor negatiu es pot canviar per 0 a l'hora de mostrar els resultats (l’exemple del qual es facilita l’enllaç ho fa així). Podeu comprovar el funcionament del programa amb l'enllaç: http://comoras.uoc.edu/~jgilm/ PAC2_exer07.php?vini=V&angle=A&unit=U en l’exemple es mostra la llista fent servir una taula, cosa que no s’exigeix en la vostra solució, en què podeu separar moment, posx i posy simplement amb espais. Indicacions: • El fitxer d'imatge shoot.png s'ha d'ubicar a la mateixa carpeta que l'arxiu php. • L’entrada de dades es farà amb el mètode $_GET per tal que l’entrada de dades es faci amb la URL com a l’exemple. Haureu de definir la constant G al valor 9.81 (expresada en metres/s2) i, en necesitar el valor de la gravetat, referenciareu la constant. Heu de crear l’a function getData que recollirà les dades passades com paràmetres a l’entrada i les retornarà. A més, comprovarà que les dades siguin correctes, és a dir: vini ≥ 0 i 0 ≤ angle ≤ 90. Si les dades són correctes, retornarà també true en una variable $ok. Altrament tornarà $ok prendrà el valor false. Heu de crear una function mToInch que rep una distància en metres i la retorna en polzades (1 polzada = 0,0254 m). Heu de crear una function calculateSpeds que rebi la velocitat inicial, l’angle i el paràmetre unit i retorni les velocitats vx i vy. En el cas que el paràmetre unit tingui el valor i, llavors les velocitats vindran expressades en polzades/s. Altrament les velocitats vindran expressades en m/s. PHP ve dotat de les funcions sin1 i cos2 per calcular sinus i cosinus respectivament. Ambdues funcions requereixen que l’angle vingui expressat en radians en lloc de en graus, per la qual cosa s’haurà de passar l’angle de graus a radians. PHP té la funció deg2rad3 que fa aquesta feina. P.e. per calcular el sinus de 30º podria fer-se sin(deg2rad(30)) • • • • 1 2 http://www.php.net/manual/es/function.sin.php http://www.php.net/manual/es/function.cos.php 3 http://www.php.net/manual/es/function.deg2rad.php 21 • Heu de crear una function calculateXPos que rep la velocitat horitzontal i un temps t i retorna la posició horitzontal de la pedra en el moment t. Heu de crear una function calculateYPos que rep la velocitat vertical i un temps t i retorna la posició vertical de la pedra en el moment t. El programa principal ha de consistir en: o Carregar les dades. o Si les dades no són correctes (velocitat negativa, angle negatiu o angle superior a 90º) indicar-ho en un missatge i no fer res més. o Si les dades són correctes § § § § § Calcular les velocitats vx i vy Escriure les dades rebudes i mostrar el diagrama de la simulació (shoot.png) Per a cada dècima de segon, i mentre no es torni a tocar terra escriure en una línia instant, posx i posy Escriure quin és l’abast de la tirada Escriure quina és l’alçada màxima assolida • • A tenir en compte • Per definir constants en PHP es fa servir la funció define4. • La funció isset5 serveix per saber si una variable ha rebut algun valor o no. Pot ser útil per saber si s’ha rebut un paràmetre en la crida. P.e. if (isset($_GET[“nom_param”]) ... En PHP els paràmetres de sortida o entrada sortida, sindiquen en la capçalera de la function afegint el caràcter & al nom del paràmetre. P.e. en function prova(&$a, $b) el paràmetre $b és d’entrada i $a és d’entrada/sortida o de sortida. En PHP existeixen algunes diferencies interessants respecte del llenguatge algorísmic: o Per fer operacions no cal convertir enters en reals o a l’inrevés, les conversions són automàtiques. o Recordeu que l'operador de comparació en PHP és el doble igual ==. L'operador = és l'operador d'assignació. o Per sumar una quantitat a una variable, és còmode fer servir l'operador +=. Per exemple $a += 0.1; equival a $a = $a + 0.1; o Es fa servir function tant per definir accions com funcions. Les function, a més, poden funcionar com una entitat mixta, que retorni valors en paràmetres d’entrada/sortida (com les accions) i retorni un altre valor amb una instrucció return (com les funcions). P.e. function prova (&$a, $b){ $a++; return ($a * $b)/2 } • • 4 5 http://es.php.net/manual/es/function.define.php http://es.php.net/manual/es/function.isset.php 22 Enganxeu aquí el vostre llistat del fitxer PAC2_exer07.php PAC2_Exer07

PAC2_Exer07

***** Maria del Mar Ortiz Valor ******

velocitat inicial (en m/s) angle -> angle respecte l'horitzontal (en graus) unit -> paràmetre opcional que ha de prendre el valor 'i' per que la sortida es faci en polzades i escriu les coordenades x (desplaçament horitzontal) y (alçada) de la pedra amb intervals de 0.1 segon En finalitzar s'escriu quin ha estat l'abast i l'alçada màxima exercici 7 - PAC2 - Febrer-juny 2012 autor: */ /******** CONSTANTS **********/ 23 define("G", 9.81); define("polzada", 39.3700787); /******** FUNCTION **********/ //AQUI VAN LES FUNCIONS function getData(&$vini, &$angle, &$unit) { $vini = $_GET["vini"]; $angle = $_GET["angle"]; $unit = $_GET["unit"]; $ok = false; if ($vini >= 0 && $angle >= 0 && $angle <= 90) { $ok = true; } //del if else { print "ERROR: La entrada de dades no es correcta. Ha de tindre una velocitat positiva, i un angle positiu i inferior a 90º" ; } return $ok; } //de la fuction function mToInch($m, &$i) { $i = $m * 39.370079; i la constant que has definit? return $i; } 24 function calculateSpeds($vini, $angle, $unit, &$vx, &$vy) { $sinus = sin(deg2rad($angle)); $cosinus = cos(deg2rad($angle)); // print "seno del angulo = $sinus
"; // para comprobar // print "coseno del angulo = $cosinus
"; // para comprobar if ($unit != "i") { $vx = $vini * $cosinus; pots estalviar variables fent expressions més llargues $vy = $vini * $sinus; print "Unitats en metres
"; printf ("Velocitat inicial horitzontal vx = %.3f m/s
", $vx); printf ("Velocitat inicial vertical vy = %.3f m/s
", $vy); } // del if else if ($unit == "i") { $vx = ($vini * $cosinus * constant("polzada")); // falta conversio a polzades siga mitjançan la funcio mToInch, $vy = ($vini * $sinus * constant("polzada")); // falta conversio a polzades siga mitjançan la funcio mToInch, print "Unitats en polzades
"; printf ("Velocitat inicial horitzontal vx = %.3f polzades/s
", $vx); printf ("Velocitat inicial vertical vy = %.3f polzades/s
", $vy); } // del if } function calculateXPos($vx, $t, &$posx) { $posx = $vx * $t; return $posx; } function calculateYpos($vy, $t, $G, $unit, &$posy) { // $G = constant("G") * constant("polzada"); // print "g = $G polz/s
"; // para comprobar if ($unit != "i"){ $G = constant("G"); // print "g = $G m/s
"; // para comprobar } else if ($unit == "i") { $G = constant("G") * constant("polzada"); // print "g = $G polz/s
"; // para comprobar 25 } $posy = ($vy * $t) - (0.5 * $G * $t * $t); return $posy; } /******** MAIN **********/ //AQUÍ VA EL PROGRAMA PRINCIAL print "

SIMULACIO DE LA TIRADA D'UNA PEDRA

"; if ($ok = getData(&$vini, &$angle, &$unit)) { print "

Velocitat inicial en metres per segon = $vini
Angle de tir (en graus) = $angle

"; print "

"; calculateSpeds($vini, $angle, $unit, &$vx, &$vy); a les crides no es posa en & print "

Taula de desplaçaments

"; print "Temps | Distancia | Altura
"; $Vmax = 0; for ($t = 0; $posy >= 0; ($t = $t + 0.1)) { calculateXPos($vx, $t, $posx); calculateYPos($vy, $t, $G, $unit, $posy); if ($Vmax <= $posy) { $Vmax = $posy; } printf ("%.1f | %.3f | %.3f
", $t, $posx, $posy); } if ($posy <= 0) { print "
"; 26 printf ("Abast: %.3f ", $posx); if ($unit != "i"){ print "metres
"; } else { print "polzades
"; } } printf ("Alçada maxima: %.3f ", $Vmax); if ($unit != "i"){ print "metres
"; } else { print "polzades
"; } }// del if getData ?>
Qualificació B 27