Curso de PHP – Clase 8 – Resolución de ejercicios propuestos

En este artículo voy a resolver los ejercicios propuestos que corresponden a la Clase 8 del Curso de PHP sobre el tema arrays multidimensionales. Como los enunciados son un poco largos, decidí omitirlos en este texto, así que si quieren recordarlos, pueden ir al final de la clase teórica enlazada previamente, que es donde se encuentran.

En cada ejercicio aparecerá un link al código fuente completo y otro con el código interpretado por PHP.

Ejercicio 1

El código fuente de este ejercicio se encuentra aquí y el código funcionando, aquí.

En este primer ejercicio vamos a combinar lo aprendido de arrays multidimensionales, formularios y una pizca de CSS. Recuerden que las hojas de estilos sirven para presentar la información. Que no sea un lenguaje de programación no significa que no tenga que aprenderse, y tampoco significa que sea un tema vinculado exclusivamente a los diseñadores. No lo subestimen.

Vamos a definir los países de la forma en que se pide en el enunciado. Aquí mostraré los dos primeros únicamente:

Como ven, un array dentro de otro, es decir, de dimensión 2. Los arrays interiores son asociativos. Tienen campos que definen las columnas de la tabla.

El documento HTML tiene definida una tabla primero y luego un formulario. Veamos primero la tabla.

Se definen las cabeceras y luego, mediante dos foreach, uno dentro de otro, se recorren primero filas y luego columnas de este array asociativo. Enseguida analizaremos el atributo class y su relación con el parámetro que viene por post, pero antes veamos el formulario.

El atributo action dice que se enviará a sí mismo y el atributo method indica que lo hará mediante el método post. El elemento principal de este formulario es un campo de texto llamado opcion, que inicialmente no tiene valor, pero que el usuario puede introducir.

Cuando la página cargue por primera vez, se mostrará la tabla. Si prestan atención al código verán algo de código CSS para mejorar la presentación. Debajo de la tabla, aparecerá el campo de texto para ingresar la opción por teclado y un botón del tipo submit o enviar. No olviden que el valor que debe ingresar el usuario se corresponde con el valor de la columna id que se muestra en la tabla de países.

Ahora veamos como hacer para pintar las filas según el valor de la opción ingresada.

Luego de la definición del array multidimensional aparece lo siguiente:

Recuerden, la función isset hace verdadera la condición si la variable $_POST[‘opcion’] esta definida y hace la falsa, de lo contrario. En caso de que sí esté definida, la variable $clase tomará el valor ‘normal’, que es una cadena de caracteres.

Ahora volvamos a los bucles foreach que imprimían la tabla

Las etiquetas <tr> definen filas en las tablas. Mediante el atributo class es posible asociarles estilos de CSS. Si quisiéramos, podríamos ponerle el nombre de una clase de CSS que hayamos definido más arriba, en la sección correspondiente, y la fila tomaría el formato que la clase indique.

Sin embargo, no es lo que estamos buscando aquí. Necesitamos que la fila tome formato únicamente del país elegido. ¿Cómo podemos hacer eso? Con una sentencia condicional que compare el valor de la opción que viene como parámetro con el id del país que se está por imprimir en el documento HTML.

Opté por utilizar el operador ternario de PHP, que como ya saben, realiza la misma función que un if.

Si se cumple que $_POST[‘opcion’] es igual a $pais[‘id’], entonces se imprime ‘elegido’; de lo contrario, no se imprime nada y es por eso que aparece ese null, que corresponde al valor vacío e indefinido. También se podría haber puesto ‘ ‘, es decir, una cadena de caracteres sin nada dentro.

Esta estructura condicional asegura que solo en un caso se pintará una fila, suponiendo siempre que el valor de id de los países no se repiten. La clase CSS está definida entre las etiquetas <style> y </style> en la cabecera del documento.

El punto delante del identificador indica que se trata de una clase. Entre llaves se ponen los atributos y estos se definen con nombre clave y un valor. En este caso, al color de fondo (background-color), se le asigna el valor rojo (red). Puesto que la clase está asignada a una fila <tr>, entonces la fila lucirá con fondo rojo en la presentación.

Ejercicio 2

El código fuente de este ejercicio se encuentra aquí y el código funcionando, aquí.

Este tipo de ejercicio es común en informática, sin importar el lenguaje. Tener una lista de registros y una lista con actualizaciones puede ser útil para procesar archivos, por ejemplo.

Entonces, por un lado tenemos una tabla con discos de música cuyas columnas son las siguientes: identificación, título, artista y precio. Por el otro, una tabla de precios para actualizar con las columnas de identificación y con el nuevo precio. El número identificatorio de la tabla de actualización se vincula con el de identificación de la tabla de discos.

Antes de realizar ninguna tarea, vamos a mostrar la tabla original con los discos de música. Para ello, vamos a utilizar dos bucles for, uno dentro de otro.

El mismo tipo de estructura cíclica que habíamos visto en la clase teórica. Un for dentro de otro, cada uno con una variable distinta a la hora de contar. Se envuelve el bucle interno en etiquetas <tr></tr> para definir las filas. Dentro de este bucle, aparecen los elementos del array, cuyo primer índice es la variable del bucle externo y el segundo, del interno. El resultado, será una bonita tabla en HTML, con algo de formato en este caso puesto que hay algunas líneas de CSS definidas más arriba en el documento.

Ahora pasemos a la actualización de los datos. Vamos a ir pasando cada fila de la lista con la actualización y por cada una de ellas, se recorrerá la tabla original en busca del disco que hay que actualizar comparando siempre los identificadores numéricos, que se suponen, deben ser únicos.

En este caso, un foreach por fuera, pasando cada elemento del array $actualizacion como la variable $item. Por dentro, un for que recorre todas las filas del otro array, el que tiene la lista completa de discos, y en cada uno de los pasos, se verifica si la fila con el precio a actualizar tiene el mismo número de identificación (primera columna de la tabla) que la columna correspondiente en la tabla de discos. Si esto se cumple, se actualiza el precio del disco (cuarta columna de la tabla) tomando el valor que tiene la columna ‘precio’.

Hay algunas consideraciones vinculadas a la eficiencia en que se lleva adelante esta actualización. Una vez que se encuentra el disco a actualizar, el bucle interno seguirá buscando. Si se entiende que el número de identificación es único, entonces aquí habría que buscar una manera de evitar esas iteraciones adicionales. Pero en este ejemplo, para no añadir mayor dificultad al problema, no se han considerado. Sólo tengan en cuenta que en una aplicación real, sí habría que considerarlo.

Luego, queda por volver a mostrar la tabla con los datos actualizados. Eso se puede hacer con el mismo bucle que al principio.

Ejercicio 3

El código fuente de este ejercicio se encuentra aquí y el código funcionando, aquí.

Al leer el enunciado puede parecer demasiado, pero no hay que asustarse. Siempre hay que analizar todo por partes y tratar de descomponer el gran problema en problemas más pequeños.

Partimos de un fixture de fútbol, que tiene la siguiente forma de array multidimensional:

Cada fila representa un partido jugado, con su correspondiente resultado. La primer columna indica el nombre del equipo local y la segunda los goles que marcó. La tercera columna indica el nombre del equipo visitante y la cuarta, la cantidad de goles que convirtió.

En total hay 6 encuentros, que corresponden a un cuadrangular en el que los equipos juegan todos contra todos. En base a los resultados de este fixture, hay que armar la tabla de posiciones o la clasificación (para los españoles) con algunos datos estadísticos.

Vamos a definir el array multidimensional que llevará estas estadísticas.

El primer elemento de las filas, que corresponden al equipo y sus números asociados tiene como primera columna el nombre del club, luego, vienen 7 valores enteros que se corresponden a partidos jugados, ganados, empatados, perdidos, goles a favor, goles en contra y puntos. En ese orden. Noten que todos estos valores están inicializados en cero, puesto que construiremos un algoritmo que vaya recorriendo el fixture e incrementando las estadísticas según corresponda.

Como vamos a recorrer el fixture, utilizaremos un for, aunque podría haberse elegido cualquier otro bucle.

A veces, trabajar con valores obtenidos de arrays asociativos hace que el código se ponga incómodo para leer. La superpoblación de índices va en contra de uno de los primeros preceptos de la programación y es que los nombre de las variables sean descriptivos y auto referenciales, es decir, que al leer el nombre de una variable, se sepa qué significa el valor que tiene definido. Por este motivo, haremos lo siguiente

Es decir, durante todo el bucle for, pasamos los valores un poco difíciles de identificar del array $fixture, a variables mucho más entendibles. $local hace referencia al nombre del equipo local, $visita al nombre del equipo visitante, $goles_local son los goles convertidos por el equipo local y $goles_visita por el equipo visitante. ¡Mucho más fácil de comprender! ¿No creen?

Entiendan que cuando trabajamos dentro del for, en cada iteración estaremos analizando una fila del array $fixture, esto quiere decir que en cada iteración, estaremos analizando un partido de fútbol.

Primero vamos a determinar qué resultado tuvo el partido: victoria local, empate o victoria visitante. Para ello, usaremos la siguiente estructura.

Queremos definir si hubo ganador y perdedor o si hubo empate. Usaremos las variables $ganador y $perdedor para almacenar los nombres de los equipos, según sea el resultado y la variable $empate que es booleana (solo admite valor true o false) para determinar si hubo empate.

Pensemos esto de la siguiente manera. Damos por sentado que no hubo empate, por eso ponemos la variable $empate en false. Luego preguntamos si hubo más goles del visitante que del local, si esto es así, entonces $ganador tomará el valor de $local y $perdedor de visitante.

Si no es así, si hubo más goles de la visita que del local, entonces será al revés: $ganador tomará el valor de $visita y $perdedor el de $local. No pierdan de vista que los valores que se están asignando son los nombre de los equipos de fútbol.

Pero puede haber un caso más, en el que ninguno haya hecho más goles que el otro. Naturalmente este caso es un empate. Por lo tanto, nuestra primera suposición no era cierta y debemos cambiar el valor de la variable $empate a true.

Una vez que se atraviesa ese código, queda en $ganador el nombre del equipo que ganó, en  $perdedor el del equipo que perdió y $empate queda en true si hubo empate o en false si no lo hubo.

Ahora llega el momento de actualizar la tabla de posiciones. Primero veremos el caso en el que hubo empate:

Noten que en el if no comparo con true o con false. Directamente utilizo el valor de $empate. Esto es optativo. Luego, dentro del if se realiza un for para recorrer la tabla de posiciones.

Con la tabla de posiciones, no conviene utilizar variables adicionales que faciliten la lectura del código, puesto que habría que asignarlas primero, luego actualizar las que fueron pasadas y finalmente, volverlas a asignar a las originales. Esto sería mucho más desprolijo que utilizar los subíndices directamente.

Aquí se usa la sugerencia que aparecía en el enunciado, para identificar los nombres de los equipos. La función strcmp, a la que pueden llamar string compare sirve para comparar cadenas de caracteres. Ya la veremos en profundidad la próxima clase teórica, pero por ahora nos alcanza con saber que lleva dos parámetros y que deben ser cadenas de caracteres. Si ambas son iguales, devuelve el número 0. Por eso, el if que está en el código realiza esa comparación con el 0.

¿Qué es lo que se está chequeando en esos if donde aparece la función strcmp? Que el nombre del equipo que hay en $local y $visita coincidan con la primera columna de la tabla de posiciones. En otras palabras, se está buscando en la tabla de posiciones el equipo que corresponde.

Una vez identificado, se actualizan los valores. Es similar tanto para el local como para el visitante. Se suma un partido jugado a la segunda columna (la de partidos jugados), se le suma una unidad como partido empatado a la cuarta columna, se agregan los goles a favor y los goles en contra en las columnas correspondientes y por último, se suma un punto por partido empatado.

Si no hubo empate, entonces tenemos el siguiente código.

Se recorre nuevamente la tabla y se busca el nombre del equipo con strcmp, pero en este caso, utilizando las variables $ganador y $perdedor, para saber en cada caso la forma correcta de actualizar las estadísticas.

Para el ganador, se sumará un partido jugado, uno ganado, los goles a favor y en contra y los tres puntos por haber obtenido la victoria. Para el perdedor, cambia que se suma una derrota y no se suma ningún punto.

Se cierra el bucle for que recorría el fixture y estaremos seguros de que la tabla de posiciones está actualizada. Pero falta algo importante, hay que mostrarla por pantalla y para eso, debe estar ordenada por cantidad de puntos obtenidos.

Para ordenar arrays multidimensionales, hemos visto un método en la clase teórica. Vamos a utilizarlo.

Copiamos la columna número 7 (la octava) de puntos obtenidos de $posiciones a un array llamado $puntos. Este lo usamos de referencia en la función array_multisort. Indicamos el orden descendente y pasamos por parámetro el array a ordenar que es $posiciones. Si lo están pensando, en caso de igualdad de puntos no estamos teniendo en cuenta la diferencia de gol ni ningún otro parámetro.

Y listo, con combinación de bucles que quieran utilizar, podrán recorrer la tabla de posiciones y mostrarla por pantalla.

Ejercicio 4

El código fuente de este ejercicio se encuentra aquí y el código funcionando, aquí.

Este ejercicio, que parece rebuscado, en realidad está vinculado con el chequeo de paridad que se hace al almacenar o transferir información entre elementos de los sistemas computacionales. El tema de la paridad es bastante importante y les recomiendo que lo investiguen. Lo que vamos a hacer a continuación, no obstante, es simplemente un ejercicio que solamente toma algunos aspectos de este asunto.

En principio, hay que generar una matriz (o tabla) con unos y ceros que se deben generar de forma aleatoria.

Como la matriz está siendo definida, no se puede saber el tamaño. Es por eso, que se corren los for utilizando el valor tope que dice el enunciado. ¡Recuerden que se empieza a contar desde 0! Por lo tanto, de esta forma nos aseguramos que haya 9 filas y 15 columnas.

La función rand ya la vimos en ejercicios anteriores. Recibe dos parámetros: dos números enteros, que definen un intervalo. Los enteros que estén entre ese intervalo, incluidos ellos mismos, son los posibles resultados de rand. En este caso, al estar acotado entre 0 y 1, los resultados solo pueden ser 0 ó 1.

Vamos a recorrer por columnas, algo que hasta ahora no habíamos hecho y a calcular la paridad. Si la suma de una columna es un número par entonces decimos que esa columna tiene “paridad par” y si es impar, “paridad impar”

Se recorre por columna, noten que se harán 15 iteraciones con el for externo. Se inicializa una variable $suma a cero, que será la que acumulará el valor de cada columna. En el for interno, se recorren las filas de esa columna sumándolas en $suma. Presten atención que los índices de $matriz están invertidos, ya que estamos recorriendo primero por columna y luego por fila.

Al salir del for interno, $suma tiene un valor que es o bien par o bien impar. Para ver qué es, usamos el operador % que es el resto de la división entera. Haciendo resto se suma entera de $suma y 2,  y obtenemos el resto que si es igual a 0, significa que el valor era par y si es 1, impar.

Cualquiera sea el caso, como pide el enunciado, la palabra ‘par’ o ‘impar’ se agrega a la última fila, la número 9 (la décima) de la columna que corresponde.

Para mostrar todo por pantalla, se pueden hacer dos bucles clásicos:

Ejercicio 5

El código fuente de este ejercicio se encuentra aquí y el código funcionando, aquí.

El objetivo de este ejercicio es aprender a procesar datos, como si provinieran de un archivo o de una base de datos. Se tiene un array multidimensional con mucha información acerca de empleados que trabajan en alguna empresa y se pide un resumen de esa información enfocado en algunos puntos en particular. El array ya venía definido en el enunciado así que no voy a volver a incluirlo aquí.

Hay que empezar a ver algunas cosas antes de ponerse manos a la obra. Habrá que calcular el promedio de los sueldos, lo que significa que hay que calcular primero la suma de todos ellos. También hay que encontrar un máximo que corresponde con el empleado que más dinero gana. También hay que contar cuántos empleados administrativos hay en la tabla.

Todo esto es importante tenerlo presente porque vamos a necesitar ir definiendo e inicializando algunas variables antes de empezar a recorrer la tabla.

La primera variable, $max_sueldo alojará el valor que corresponde al máximo sueldo, pero al comenzar el ciclo, tomará el valor del sueldo del primer empleado. Luego, usando el algoritmo para encontrar el mayor, irá cambiando si es necesario. Al finalizar el ciclo, nos aseguraremos que el valor será el máximo. $mejor_pago está relacionado con esta última variable puesto que tendrá el nombre del empleado que más gana.

La variable $sueldos será la que acumule la suma de todos los salarios y que luego será dividida por la cantidad de empleados para obtener el promedio. $admins es un simple contador que se irá incrementando en uno cada vez que se encuentre un empleado administrativo.

Esta vez, con un foreach para recorrer por filas. Este foreach tiene una particularidad: antes de la variable $fila, aparece un signo &. Esto es así porque de no utilizarse, no podría ser posible modificar los valores de las filas. Este operador &, está asociado al pasaje de datos en PHP, tema que veremos recién dentro de dos clases, cuando llegue el momento de analizar a fondo las funciones. Por ahora, pensemos que ese & nos permite modificar el valor de las filas.

La tercera columna de la tabla indica el sueldo del empleado y será la que se irá sumando a $sueldos.

Para obtener el que más gana, usamos el algoritmo de hallar el máximo. Se compara el máximo actual con el sueldo de cada empleado. Cuando este supera al máximo, lo reemplaza.

Para contar la cantidad de administrativos que hay, usamos strcmp, al igual que en el ejercicio de los equipos de fútbol. El primer parámetro será el puesto del empleado y el segundo, la cadena de caracteres ‘Administrativo’ que tiene que estar escrito de la misma manera que figura en el array.

Además de todo esto, el ejercicio pedía subir el sueldo en un 25% a todos los empleados. Esto se hace actualizando el valor de la columna número 2. Una suba del 25% la podemos pensar de la siguiente manera. Tomamos el valor del sueldo y le sumamos el valor del sueldo multiplicado por 0,25.

Por último, el enunciado pide eliminar a los empleados cuyo puesto es Mantenimiento. Usamos una vez más strcmp y la función unset, para eliminar arrays.

En el cuerpo del documento HTML mostramos lo que nos piden.

Y un bucle for para mostrar la lista actualizada.

Y llegamos al final de este artículo. Nos encontramos nuevamente en la próxima clase teórica.

Soy programador web y me desempeño como Líder Técnico y de Proyectos en Polar Bear Development. Trabajo con tecnologías como PHP, Javascript, MySQL y HTML5 para el desarrollo de sitios y sistemas web. Me especializo en Zend Framework 2 y otros frameworks MVC, como también en WordPress y otros CMS. Lidero equipos de desarrolladores trabajando con Scrum. Vivo en Buenos Aires, Argentina.
 

2 thoughts on “Curso de PHP – Clase 8 – Resolución de ejercicios propuestos

  1. Muy claro tus ejercicios y prácticos. Muy buen aporte.
    En el caso del ejercicio 3 cómo se puede pasar para POO, con base de datos en Mysql. Gracias

  2. Hola Marco Antonio

    Sería un poco largo explicarlo por completo aunque es claro que sería más útil que trabajarlo con base de datos que con arrays. Debería haber seguramente una tabla de posiciones, quizás una tabla más de equipos, de esta forma si luego hay más campeonatos, no habría que repetir una columna “equipos” en cada una. Pensarlo orientado a objetos sería interesante, se me ocurre modelar las clases Equipo, Partido, TablaDePosiciones, si lo pienso rápido.

    Quizás en algún momento pueda volver sobre este ejercicio y rehacerlo orientado a objetos.

    Saludos

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*