Document exercicis PAC2 - El blog d'un estudiant de la...

15
Estudis d’Informàtica, Multimèdia i Telecomunicació Programació PAC2 — Document d’exercicis Cognoms: Amengual Gomila Nom: Pere 1

Transcript of Document exercicis PAC2 - El blog d'un estudiant de la...

Estudis d’Informàtica, Multimèdia i Telecomunicació

ProgramacióPAC2 — Document d’exercicis

Cognoms: Amengual GomilaNom: Pere

1

Exercici 1: Declaració d'accions i funcions [15%]

Tasca: Per a cada apartati. decidiu si és millor una acció o una funció i expliqueu el motiu.ii. 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:

a) Que rebi tres paraules i les escrigui a la sortida estàndard ordenades per ordre alfabètic:

i És millor una acció, ja que no és necessari que retorni cap valor (es limita a escriure les paraules a la sortida estàndard) i la seva invocació tampoc requereix que formi part d'una expressió.

ii accio escriuOrdenades (ent paraula1: text, ent paraula2: text, ent paraula3: text )

b) Que reculli de l'entrada estàndard una llista de números amb decimals i digui quin és el major i el menor que havia a la llista.

i És millor una acció ja que recull les dades de l'entrada estàndard i no de paràmetres d'entrada; a més, retorna més d'un paràmetre.

ii accio escriuOrdenades (sor major: real, sor menor: real )

c) Que rebi el nom d’un fitxer d’imatge i el codi numèric d’un color i retorni la quantitat de píxels del dit color que conté el fitxer d’imatge

i És millor una funció ja que retorna un sol valor a partir d'uns paràmetres d'entrada i el valor que retorna és l'únic efecte de la funció.

ii funcio nombrePixels (nomfitxer: text, codiColor: enter): enter

d) Que llegeixi de l’entrada estàndard una llista de números i digui si la llista conté algun 0.

i És millor una acció ja que recull les dades de l'entrada estàndard i no de paràmetres d'entrada;

ii accio conteZero (sor zero: booleà )

2

Exercici 2: Crides a mòduls i modificadors d'entrada i sortida [15%]Tasca: Donats l’algorisme i les capçaleres de les següents accions i funcions:

funcio function1( x: enter, y: enter, z: real) : boolea;

funcio function2( x: enter, c: caracter, b: boolea) :enter;

accio action1( ent i: enter, ent j: enter, sor k: enter) ;

accio action2( ent c: caracter, ent x: real, entsor y: enter);

algorisme algorithmvar i, j, k: enter; x, y, z : real; d : caracter; b: boolea;fvar

...

...

falgorisme

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) action1 (function2(i, d, (x>y)), k,j);Correcte. Els tipus de tots els paràmetres que s'han fet servir es corresponen amb els definits a les capçaleres.Action1 (function2(enter,caracter,boolea), enter, enter)Action1(enter, enter, enter)

b) b := function1(k, k, y) > integerToReal(i*i) + x / 2Incorrecte. No es pot dividir “x”, un nombre real, per “2”, un enter.b:= function1(enter,enter,real) > integerToReal(enter*enter) + real/2b:= enter > integerToReal(enter*enter) + real/2boolea= enter > real + real/enter

c) i := action2( ‘x’, 3.1416, k * j);Incorrecte. Una acció mai pot formar part d'una expressió.

3

Exercici 3: Ús de mòduls i paràmetres segons el seu significat i [15%]

Tasca: Amb motiu de la introducció de minijobs, una multinacional demana un algorisme per calcular la nòmina en els següents termes. El treballador cobra un preu fix per hora i li retenen un percentatge en concepte de IRPF que depèn de la quantitat que ha de cobrar al mes. L'algorisme ha de llegir el número d'hores treballades i el preu per hora que cobra des de l'entrada estàndard (teclat) i ha d'escriure al canal de sortida estàndard (pantalla) el sou brut, la retenció de IRPF i el sou net. Si el sou brut mensual no supera els 300€ no hi ha retenció i s'escriurà directament el sou net. Si el sou brut supera els 300€ i no supera els 600€ la retenció d'IRPF és del 5%. Si supera els 600€ la retenció és del 8%. En ambdós casos s'escriurà salari brut, retenció i salari net.

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 totes les següents funcions, que no heu d’implementar:

funció que rep es salari brut i el tipus a aplicar d'IRPF i calcula l'import de la retenció.

funcio calcRetention ( grossSalary: real, irpf: real) : real

funció que rep el salari brut i l'import de la retenció i calcula el salari netfuncio calcTakeHomePay ( grossSalary: real, retention: real) : real

4

algorisme payroll ( )

const IRPF_low: real = 5.0; IRPF_high: real = 8.0; SALARY_THRESHOLD_LOW: real = 300.0; SALARY_THRESHOLD_HIGH: real = 600.0; fconst

var fixedHourPrice, workedHours: real; grossSalary, retention, takeHomePay: real;

fvar

fixedHourPrice := ; workedHours := ; grossSalary := fixedHourPrice * workedHours;

si llavors

si grossSalary > SALARY_THRESHOLD_HIGH llavors

retention := ; sino retention := ; fsi sino retention := 0; fsi

takeHomePay := ;

si llavors writeReal (grossSalary); writeReal (retention); writeReal (takeHomePay); sino writeReal (takeHomePay); fsifalgorisme

5

llegirReal()

llegirReal()

calcRetention ( grossSalary, IRPF_high )

calcTakeHomePay ( grossSalary, retention )

Retention ≠ 0

GrossSalary > SALARY_THRESHOLD_LOW

calcRetention ( grossSalary, IRPF_low )

Exercici 4: Disseny de mòduls [15%]

Un alpinista viatja sovint amb companys de cultura anglosaxona que estan acostumats a mesurar les temperatures en graus Fahrenheit, mentre d'altres companys estan acostumats als centígrads. Existeixen fórmules simples per fer les conversions que es poden veure a http://ca.wikipedia.org/wiki/Grau_Celsius

Tasca: Crear un mòdul (acció o funció, el més adequat) que serveixi per entrar la temperatura en una donada escala (escala d'entrada) i obtenir-la en una altra escala (escala de sortida) i justifiqueu el motiu de la tria. El mòdul ha de rebre tres paràmetres, que correspondran a:

• Escala d'entrada de dades (un caràcter: C o F).

• Escala de sortida de dades (un caràcter: C o F).

• Valor de la temperatura d'entrada

S'ha de preveure la possibilitat que les dues escales (entrada i sortida) siguin la mateixa.

Una funció és la manera més adequada ja que només ha de retornar un valor. He tengut en compte que no ens demanen que retorni també en quina escala ens retorna aquest valor, en aquest altre cas hauria estat més adequat fer servir una acció. En cas de que el mòdul rebi valors distints de ‘C’ o ‘F’ la funció retorna la temperatura de -1000.0, que l’algorisme principal pot interpretar com un error. Els casos que retornin valors de sortida impossibles en el món real deguts a valors d’entrada fora de la escala de temperatures possibles es deixen a interpretació per part de l’algorisme principal, seguint el principi de “Garbage In, Garbage Out”.

funcio convertirTemp( escalaEntrada: caracter, escalaSortida: caracter, temperaturaEntrada:real): real

var temperaturaSortida :real; fvar

temperaturaSortida := -1000.0 ;

si ((escalaEntrada = ‘C’ i escalaSortida = ’C’) o (escalaEntrada= ’F’ i escalaSortida = ‘F’) ) llavors temperaturaSortida := temperaturaEntrada;sino si (escalaEntrada = ‘C’ ) llavors temperaturaSortida := (temperaturaEntrada - 32.0) /1.8 ; sino si escalaEntrada = ‘F’ llavors temperaturaSortida := (temperaturaEntrada * 1.8) + 32.0 ;fsi

return temperaturaSortida

ffuncio

6

Exercici 5: Creació d'un programa amb mòduls a PHP [20%]

Tasca: Heu de crear un programa que calculi i escrigui en pantalla una factura detallada de la companyia de subministrament d'aigua a partir dels litres de consum trimestral.

La factura del subministrament d'aigua inclou diferents conceptes:• Consum pròpiament dit (consumption)• Taxa de clavegueram (sewer)• Lloguer del comptador d'aigua (watermeter rent)• Canon d'obres hidràuliques (canon)

cadascun dels qual ve gravat amb l'IVA corresponent

! Per tal d'afavorir el consum responsable, s'ha creat una tarificació per blocs, de manera que quant més gran sigui el consum, major és el preu unitari del metre cúbic d'aigua. La tarificació per blocs afecta de manera diferent els conceptes de consum i el de canon.

El mecanisme de tarificació és com segueix:•Consum:

o 1r bloc (0-20m3) : 0.437 €/ m3

o 2n bloc (20-40m3) : 0.6554 €/ m3

o 3n bloc (>40m3) : 0.824 €/ m3

Si un usuari consumeix 65 m3, en pagaria 20 a 0.437, uns altres 25 a 0.6554 i els restants 14 a 0.824.

•Clavegueram Amb aquest concepte es paga el 25% del que es paga per Consum.

•Lloguer del comptadorEs paga la quantitat fixa de 1.92€ cada trimestre

•Canon: o 1r bloc (0-18m3) : 0.4469 €/ m3

o 2n bloc (18-30m3) : 1.0294 €/ m3

o 3n bloc (>30m3) : 2.57 €/ m3

Si un usuari consumeix 65 m3, en pagaria 18 a 0.4469, uns altres 12 a 1.0294 i els restants 35 a 2.57.

•IVA: Existeix tres tipus d'IVA a aplicar als diferents conceptes:o Clavegueram: exempt d'IVA (0%)o Consum i Canon : tipus reduït (10%)o lloguer del comptador: tipus normal

(21%)

la crida haurà de ser del tipus http://localhost/pac2_exer5?vol=x on x és la quantitat de litres consumits en el trimestre.

Indicacions:

7

• Per tal que el programa sigui fàcilment actualitzable, es definiran tantes constants amb nom com sigui necessari, de manera que si canvien els preus per m3 (de consum o canon), els volums de cada bloc (de consum o canon), el percentatge que significa la taxa de clavegueram o els tipus d'IVA, n'hagués prou en modificar les definicions de les constants perquè el programa quedés actualitzat a la nova situació. Per a la definició de constants s’ha d’emprar define($name, $value)1

• S'haurà de crear la function literToM3 que rebrà un volum en litres i retornarà la quantitat entera de metres cúbics a què equival (per truncament). Per exemple, si es rep 65789 es retornarà 65.

• S'haurà de crear la function consumption que rebrà la quantitat de m3 consumits i retornarà, en tres paràmetres, la quantitat de m3 corresponents a cada bloc de consum. Per exemple, si rep 26, retornaria 20, 6 i 0. Si rebés 65, els retorns serien 20, 20 i 25.

• S'haurà de crear la function canon que rebrà la quantitat de m3 consumits i retornarà, en tres paràmetres, la quantitat de m3 corresponents a cada bloc de canon. Per exemple, si rep 26, retornaria 18, 8 i 0. Si rebés 65, els retorns serien 18, 12 i 35.

• S'haurà de crear la function IVA que rebrà la base a cotitzar i el codi tipus a aplicar (0→ exempció, 1→ normal, 2→ reduït). Per exemple, per a una base de 50, si el tipus és 0, es retornaria 0 (el 0%), si el tipus fos 1 es retornaria 10.5 (el 21%) i si el tipus fos 2 retornaria 5 (10%).

El programa s'escriurà en el fitxer pac2_exer5_plantilla.php que es canviarà de nom a pac2_exer5.php pel lliurament

Indicacions per a PHPLes dades s’entraran pel mètode $_GET en el paràmetre de nom vol. La crida ha de ser del tipus:

http:// localhost/pac2_exer5.php?vol=65789

Per a comprovar el funcionament podeu fer servir

http://prog.uoc.edu/pac2/pac2_exer5.php?vol=65789podeu provar el comportament del programa per a diferents valors de l'argument. A la solució d'exemple, les dades escrites formen part de taules. No és imprescindible que a les vostres solucions les dades estiguin tabulades sempre que la seva lectura sigui clara i es respecti el contingut de les línies

Advertiment

La comunicació entre el programa principal i els mòduls o bé entre mòduls, ha de realitzar-se obligatòriament mitjançant les paràmetres de les crides i de retorn. No es poden emprar variables de tipus global.

8

1 http://www.php.net/manual/es/function.define.php

Copieu aquí el codi de la vostra solució

<?php

// ************** FUNCTION **********************

//AQUI VA EL CODI DE LES FUNCTION function literToM3($lits) { //passa els litres a metres cúbics (enter) return (intval($lits/1000));}

function consumption($met3) { //rep els m3 consumits i retorna en tres paràmetres la quantitat de m3 corresponent a cada bloc de consum $tram[1]=$met3; $tram[2]=""; $tram[3]=""; if (($met3 > maxPrimerBlocConsum) && ($met3<=maxSegonBlocConsum)) { $tram[1]=maxPrimerBlocConsum; $tram[2]=$met3 - maxPrimerBlocConsum; $tram[3]=""; } elseif ($met3 > maxSegonBlocConsum) { $tram[1]=maxPrimerBlocConsum; $tram[2]=maxSegonBlocConsum-maxPrimerBlocConsum; $tram[3]=$met3 - maxSegonBlocConsum; } return $tram;} function canon($met3) { //rep els m3 consumits i retorna en tres paràmetres la quantitat de m3 corresponent a cada bloc de canon $tram[1]=$met3; $tram[2]=""; $tram[3]=""; if (($met3 > maxPrimerBlocCanon) && ($met3<=maxSegonBlocCanon)) { $tram[1]=maxPrimerBlocCanon; $tram[2]=$met3 - maxPrimerBlocCanon; $tram[3]=""; } elseif ($met3 > maxSegonBlocCanon) { $tram[1]=maxPrimerBlocCanon; $tram[2]=maxSegonBlocCanon-maxPrimerBlocCanon; $tram[3]=$met3 - maxSegonBlocCanon; } return $tram;}

function iva($base,$codi) { //rep base a cotitzar i tipus iva (0=exempció, 1=normal, 2=reduït) switch ($codi) { case 0: $impost = 0.0; break; case 1: $impost = $base * 0.21; break; case 2: $impost = $base * 0.10;

9

break; } return $impost;}

// ********** Named Constants **************

//AQUI VA LA DEFINICIO DE CONSTANTS AMB NOM define('maxPrimerBlocConsum', '20');define('maxSegonBlocConsum', '40'); define('maxPrimerBlocCanon', '18'); define('maxSegonBlocCanon', '30');

define('preuPrimerBlocConsum', '0.437');define('preuSegonBlocConsum', '0.6554');define('preuTercerBlocConsum', '0.824');

define('preuPrimerBlocCanon', '0.4469');define('preuSegonBlocCanon', '1.0294');define('preuTercerBlocCanon', '2.57');

define('percentatgeClavagueram', '0.25');

define('ivaNormal', '0.21');define('ivaReduit', '0.1');define('ivaExempt', '0');

define('lloguerComptador', '1.92'); // **************** MAIN ************************

//AQUI VA EL CODI DEL PROGRAMA PRINCIPAL $litres = $_GET["vol"]; $consumEnM3 = literToM3 ($litres); $volumec1 = consumption($consumEnM3)[1]; $volumec2 = consumption($consumEnM3)[2]; $volumec3 = consumption($consumEnM3)[3]; $importc1 = $volumec1 * preuPrimerBlocConsum; $importc2 = $volumec2 * preuSegonBlocConsum; $importc3 = $volumec3 * preuTercerBlocConsum; $totalConsum = $importc1 + $importc2 + $importc3; $importClavagueram = $totalConsum * percentatgeClavagueram; $volumet1 = canon($consumEnM3)[1]; $volumet2 = canon($consumEnM3)[2]; $volumet3 = canon($consumEnM3)[3]; $importt1 = $volumet1 * preuPrimerBlocCanon; $importt2 = $volumet2 * preuSegonBlocCanon; $importt3 = $volumet3 * preuTercerBlocCanon; $totalCanon = $importt1 + $importt2 + $importt3; $ivaConsum = iva($totalConsum, 2); $ivaClavagueram = iva($importClavagueram, 0); $ivaComptador = iva(lloguerComptador, 1); $ivaCanon = iva($totalCanon, 2); $totalIva = $ivaConsum + $ivaClavagueram + $ivaComptador + $ivaCanon; $granTotal = round(($totalConsum + $importClavagueram + lloguerComptador + $totalCanon + $totalIva),2);

?>

10

Exercici 6: Implementar les function d'un programa en PHP [20%]El programa a construir com exercici 6 haurà és una modificació del programa de la carta més alta adaptat per a que juguin entre 2 i 5 jugadors cadascun dels quals triï una determinada quantitat de cartes (entre 1 i 5). La puntuació que s'assigna a cada jugador és el valor de la de la carta més alta que ha tret segons la següent puntuació de les cartes:

Cartes Valor1 a 7 La puntuació nominal de la carta

Sota, Cavall i Rei 10 punts

La crida tindrà la forma http://localhost/pac2_exer6.php?type=E&gamers=x&qtty=n on

• type : és un caràcter que indicarà quin tipus de carta es vol mostrar:

o n o N si es vol mostrar cartes napolitanes o

o e o E si es vol mostrar cartes espanyoles

• gamers és la quantitat de jugadors, un número entre 2 i 5.• qtty : la quantitat de cartes que tirarà cada jugador, un número entre 1 i

5.

El programa haurà de complir els següents requisits:• En el cas que type tingui un valor diferent als previstos, es mostrarà la

baralla espanyola.• En el cas que gamers tingui un valor fora de l'interval marcat pels números

2 i 5, es mostrarà el joc per a 3 jugadors..• En el cas que qtty tingui un valor fora de l'interval marcat pels números 1 i 5,

es tiraran 5 cartes per jugador.• Si les dades són correctes mostrarà, per a cada jugador, les cartes que ha

tirat i la puntuació obtinguda i al final un missatge resum que digui quins jugadors han obtingut la puntuació més alta.

Tasca: Construir les function del programa per a que que sigui capaç de desenvolupar el joc previst seguint les següents

Indicacions:En les següents indicacions es descriuen les function que s'han de programar indicant el nom dels paràmetres i l'ordre en què han d'anar a la capçalera. No s'indica, en canvi, si són paràmetres d'entrada o entrada/sortida. Tampoc s'explicita si el comportament de les function correspon al d'acció o funció. Correspon a l'estudiant, a partir de la descripció que es fa de cada mòdul, decidir quins paràmetres han de tenir el nom precedit per & per ser de sortida en un mòdul que actua com a acció, i quan no hi ha paràmetre per a una sortida perquè el mòdul utilitza com a funció.

11

•S'ha de crear la function getAllData ($prefix, $gamers, $cards) que llegirà els arguments, en farà el control de valors i retornarà els valors correctes en els paràmetres. La funció, a més de corregir els possibles valors erronis que poden contenir els arguments rebuts, ha de preveure que l'usuari pot haver oblidat de posar algun o tots els arguments. Si manca un o més arguments, la funció retornarà els valors per defecte de dits arguments. Per conèixer si una variable està definida (o un argument ha rebut valor) es pot emprar la function isset2. Per exemple, per comprovar que ha la crida s'ha posat l'argument type=E caldria fer servir l'expressió isset($_GET["type"]) que prendria el valor true si existeix l'argument en la crida o bé false si ens hem descuidat de posar l'argument o no li hem donat valor. La forma habitual d'aplicar-ho a un programa és una composició del tipus: if (!isset($_GET["type"]){ accions a fer si no està posat el paràmetre o no se li ha donat valor; }

•S'ha de crear la function putCard($pref, $num) que rebrà com paràmetres d'entrada una caràcter 'e' o 'n' i el número corresponent a la imatge d'una carta i mostrarà la carta en pantalla

•S’ha de crear la function cardValue ($card) que rep el número corresponent a la imatge d'una carta (només el número) i retorna el seu valor en el joc. Per exemple si rep 32 (3 de bastos) retornaria 3, i si rebés 18 (cavall de copes) retornaria 10.

•S’ha de crear la function playerGame($player, $pref, $cards) que executa el joc per a un jugador. Rebrà el número del jugador, el prefix del tipus de baralla i el nombre de cartes a jugar.

12

2 http://php.net/manual/es/function.isset.php

Aquesta function en una línia identifica el jugador (Player 1, Player 2,...) i a la següent mostra les cartes que ha tirat i la seva puntuació.

•S’ha de construir la function printResult($winnerQtty, $bestScore, $message) que rep la quantitat de guanyadors que hi ha, la puntuació obtinguda i un missatge (quins són els jugadors guanyadors) i escriu el missatge final adequat als guanyadors.

Si hi ha un sol guanyador o Si hi ha més d'un

guanyador.

•El programa principal inicialitza comptadors, recull les dades i engega un bucle en el qual es fa jugar a un jugador cada cop i s'actualitzen els comptadors i el text que ha de tenir el missatge final. El codi del programa principal ja forma part de la plantilla i no s'ha de modificar.

•Si l’estudiant ho creu convenient pot crear més function en el programa.

Per comprovar el funcionament podeu fer servir

http://prog.uoc.edu/pac2/pac2_exer6.php?type=n&gamers=3&qtty=3

Advertiment

La comunicació entre el programa principal i els mòduls o bé entre mòduls, ha de realitzar-se obligatòriament mitjançant les paràmetres de les crides i de retorn. No es poden emprar variables de tipus global.

13

Copieu aquí el codi de la vostra solució

<?php /************* FUNCTION *************/ //Aquí va el codi de les funcions function getData (&$prefix, &$gamers, &$cards) {// llegeix arguments, controla els valors i retorna valors correctes, preveure oblit un o tots els arguments// valors per defecte: espanyola, 3 jugadors, 5 cartes per jugador

if (!isset($_GET["type"])) { $prefix = "e"; } else { $prefix=$_GET["type"]; switch ($prefix) { case 'E': $prefix = 'e'; break; case 'n': $prefix = 'n'; break; case 'N': $prefix = 'n'; break; default : $prefix = 'e'; } } if (!isset($_GET["gamers"])) { $gamers = 3; } else { $gamers=$_GET["gamers"]; if ($gamers <2 || $gamers >5) { $gamers = 3; } } if (!isset($_GET["qtty"])) { $cards = 5; } else { $cards=$_GET["qtty"]; if ($cards <1 || $cards >5) { $cards = 5; } }}

function putCard ($pref, $num) {// rep com paràmetres 'e' o 'n' i número de carta i mostra la carta en pantalla

}

function cardValue ($card) {// rep número d'imatge d'una carta i retorna el seu valor en el joc

}

function playerGame ($player, $pref, $cards) {// executa el joc per un jugador, rep número del jugador, prefix tipus baralla i nombre cartes a jugar // mostra en pantalla el jugador, les cartes que ha tirat i la puntuació que ha obtingut

14

$jugador=array(); $alta=0; echo '<h4>' . "Player " . $player . "</h4>"; for ($i=0; $i<$cards; $i++) { $jugador[$i]=rand(0,39); $mostra=$jugador[$i]; $valor=$jugador[$i] %10 +1; if ($valor >= 8) { $valor = 10; } // echo $pref . $mostra . " : " . $valor ; print "<img src='$pref$mostra.png'>"; if ( ($valor) >= $alta) { $alta = ($valor); } } echo '<b>' . "Score: " . $alta . "</b><br/>"; return $alta; }

function printResult ($winnerQtty, $bestScore, $message) {// rep la quantitat de guanyadors que hi ha, la puntuació del/s guanyador/s i un missatge que diu quí són els guanyadors// escriu el missatge adeqüat en funció de si hi ha un guanyador o més d'un. if ($winnerQtty >1) { echo '<br/><b>' . "Players " . $message . " are winners: " . $bestScore . " points"; } else { echo '<br/><b>' . "The winner is Player " . $message . ": " . $bestScore . " points"; }} // *********************MAIN********************** // init scores $winnerQtty = 0; $bestScore = 0; $message = ""; //get Data getData($type, $gamerQtty, $cardQtty); //Play for ($i=1; $i <= $gamerQtty; $i++) { $actualScore = playerGame ( $i, $type, $cardQtty); //update score if ($actualScore > $bestScore ) { $bestScore = $actualScore; $winnerQtty = 1; $message = $i; } else if ($actualScore == $bestScore ) { $winnerQtty++; $message = $message.", ".$i; } } //print results printResult($winnerQtty, $bestScore, $message);

?>

15