Saltar navegación

20250225 Exception1 - Contenido educativo

Ajuste de pantalla

El ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:

Subido el 27 de febrero de 2025 por Stefano C.

2 visualizaciones

Descargar la transcripción

Vale, entonces, si habláis, me autorizáis a grabar vuestras voces. 00:00:01
Vamos a ver un poquito rápidamente qué es el manejo de excepciones en Java. 00:00:06
Es decir, cuando surgen algún tipo de errores a tiempo de ejecución en Java, 00:00:13
¿qué puedo hacer para intentar evitar que mi programa deje de funcionar y en un cierto sentido se recupere? 00:00:19
La idea del manejo de excepciones es que errores pueden surgir y hay un mogollón de errores posibles, pero hasta ahora nosotros frente a cualquier tipo de error mi programa se acababa, pero quiero intentar evitar que esto pase. 00:00:27
A los usuarios no les gusta que mi programa se bloquee o se apague solo o que se destruya. 00:00:45
Como mínimo, si se tiene que destruir porque no puede seguir adelante, ha sido un error crítico, pues que al menos me diga algo. 00:00:52
Me diga, oye, mira, lo que has hecho está muy mal. Cuanto más detallado puedo ser, mejor. 00:01:00
Luego depende también del tipo de manejo de errores para quien lo hago. 00:01:07
Si estoy intentando hablar al usuario y hacerle entender algo o si son más bien mensajes técnicos derivantes a quien haga el mantenimiento técnico de esos programas y esos códigos, que sepa que este código es una determinada cosa, a mí me viene un código raro, yo usuario no lo entiendo, pero el desarrollador sí que podrá entenderlo, ¿vale? 00:01:13
El concepto es que una excepción es un error 00:01:37
Un fallo del programa que ocurre en tiempo de ejecución 00:01:41
A tiempo de compilación nosotros hacemos errores constantemente 00:01:44
No ponemos un punto y coma 00:01:48
Usamos un método que no existe 00:01:50
Extendemos una clase strata 00:01:52
Y no hemos implementado todos los métodos de la clase strata 00:01:55
Estos son errores que se pueden sacar a tiempo de compilación 00:02:00
O sea, antes de ejecutar el programa 00:02:04
ya el compilador o el entorno de desarrollo puede hacerme una revisión de lo que he escrito 00:02:06
y decirme, mira, aquí hay un problema. 00:02:16
Típico también meter un double dentro de variable int. 00:02:18
Él sabe que aquí hay una caja para int, tú estás poniendo un valor que es un double, 00:02:23
lo puede detectar antes de ejecutar el programa. 00:02:29
Otros errores en vez no se pueden detectar. 00:02:32
Cuando yo le digo scan.nextint diciendo que voy a leer un número, no puedo saber a tiempo de compilación que el usuario malvado en vez de un número pondrá gato. 00:02:36
Entonces, allí no puedo hacer nada a nivel de compilador de decir, oye, mira que aquí hay un error. 00:02:48
Porque el error podría no haberlo. 00:02:55
Será solo en el momento en que ejecuto que este error se podría manifestar. 00:02:57
Estos errores que se manifiestan a tiempo de ejecución son las excepciones. 00:03:03
Cuando un error ocurre, lo más normal es que se detenga el programa y se proporcione un mensaje de explique el fallo. 00:03:09
Vosotros estaréis acostumbrados cuando hay un null pointer exception, cuando hay un index out of bound exception, 00:03:15
vuestro programa se acaba, sale un listado de cosas en rojo y allí se acabó. 00:03:21
Es lo que estamos haciendo hasta ahora. Ese listado de cosas en rojo que salen es un system.out.println. Vuestro programa tiene tres canales de comunicación siempre. 00:03:31
Un input, system.in, que nosotros lo hemos visto en scanner, se lo pasamos como parámetro al scanner. Un system.out, que es el que escribe en consola, que es el que usamos nosotros ahora para decir cosas al usuario. Y luego está un system.er, que es igual a un system.out, pero está pensado para que tú escribas mensajes de errores, más que para comunicarte con el usuario, sería para comunicarte con desarrolladores que van a ver este error. 00:03:55
De hecho, muchas veces este System.er, en vez de que escriba en consola, como hacemos nosotros normalmente porque no lo tocamos, se redirecciona a un fichero. De esta forma, cuando hay errores, no aparecen al usuario, pero se apuntan en un fichero de log por ahí en algún lado. 00:04:24
De esta forma, en cierto momento, si viene el técnico y dice, mira, me pasan estos errores, a veces me hace caos, 00:04:42
pues el técnico puede acceder al fichero de log y ver qué ha pasado, cuáles han sido los errores 00:04:48
y en qué días normalmente, quién es el usuario que las ha hecho, etc., etc., etc., 00:04:55
para intentar sacar algo en claro de qué está pasando. 00:05:01
Entonces, cuando pasa una excepción, nosotros veremos en system.error, 00:05:07
Entonces los que ven rojo salen toda esa información que sustancialmente es la pila de llamadas de métodos. 00:05:11
Es decir, quién ha llamado qué, quién, qué ha llamado quién, qué ha llamado quién, qué ha llamado quién, hasta dónde se ha verificado el error. 00:05:17
Entonces si yo tengo un index out of bound exception, pues me la he hecho en esta línea de mi programa, que ha llamado un método de otra clase que era siempre mi programa, 00:05:24
pero este método estaba usando un array que entonces era la clase que gestiona el array 00:05:37
que ya no es mi programa, ya es JDK, ya es algo a nivel más de Java Virtual Machine 00:05:41
y de allí abajo, abajo, abajo, hasta llegar a los puntos donde se ha explotado 00:05:47
yo puedo seguir esas llamadas para saber qué ha pasado, dónde ha sido el error 00:05:51
cuál es la línea que la ha provocado, pero a quién llamaba y quién estaba ejecutando en ese momento el procesador 00:05:57
para saber, para enterarme un poquito más de qué ha pasado en ese momento 00:06:03
Yo proporciono un mecanismo 00:06:06
Para controlar situaciones que normalmente provocarían 00:06:09
Interrupciones en ejecución 00:06:11
Permitiendo gestionar el comportamiento 00:06:13
Del programa en caso de error 00:06:15
¿Cuál es ese mecanismo? 00:06:16
¿El único mecanismo que sabéis vosotros de gestión de errores? 00:06:27
Try-catch 00:06:31
El try-catch es un mecanismo 00:06:32
De ejecutar 00:06:35
Este programa, este trozo de código 00:06:36
Si pasa algo 00:06:39
Recoge 00:06:42
sketch la excepción que ha sido lanzada 00:06:44
y a ese punto en vez de acabar el programa 00:06:46
ejecuta otro código 00:06:50
que sustancialmente lo que debería hacer es 00:06:53
o terminar bien el programa 00:06:55
diciendo, mira ha habido un error, lo siento mucho, ha pasado esto, hasta luego 00:06:58
o intentar recuperarse 00:07:01
decir, mira los datos que me has dado no están correctos 00:07:04
o has intentado un acceso que no podías o lo que sea 00:07:07
y volver al menú principal diciendo 00:07:10
venga, inténtalo otra vez, porque ha fallado la operación, pero el programa sigue funcionando. 00:07:13
Cuando yo pienso en los errores, a este tipo de cosas que pueden pasar, hay dos formas de gestionarlo. 00:07:22
Uno es el manejo de errores o la programación pesimista. 00:07:30
La programación pesimista es intentar crear formas, crear código que evita los errores. 00:07:34
proteger zonas peligrosas usando if o usando algún tipo de comando 00:07:40
que pueda verificar que lo que estás haciendo es correcto antes de hacerlo 00:07:46
por ejemplo preguntarse si un objeto no es null antes de utilizarlo 00:07:51
entonces si yo hago un if mi objeto not null 00:07:58
estoy activamente verificando que este objeto no sea null 00:08:01
si es null te diré, oye mira no lo puedo usar 00:08:07
Si no es null, ya lo puedo utilizar, evitando así un null pointer exception. Es pesimista porque principalmente estoy sobrecargando el programa de muchos if. 00:08:09
En un programa normalmente, la mayoría de las veces 00:08:26
Los objetos que uso no deberían ser null 00:08:31
Debería ser algo 00:08:35
Yo estoy en una secretaría para alumnos 00:08:36
Estoy gestionando alumnos 00:08:38
Mientras gestiono los alumnos, los cargo de la memoria 00:08:40
Los uso, los actualizo y cosas por el estilo 00:08:43
Siempre me espero que esté trabajando con un alumno 00:08:44
Es difícil que haya buscado un alumno 00:08:47
Y justo ese alumno me haya dado null 00:08:50
Y entonces ahora estoy trabajando con un objeto null 00:08:51
Sin embargo, en la modalidad pesimista 00:08:54
Lo que estoy haciendo es comprobando 00:08:57
Cada vez que uso un objeto 00:08:59
Si ese objeto es bueno 00:09:01
Y a lo mejor hace 3, 4, 5 comprobaciones 00:09:02
De maestro es null, maestro es mayor que 0 00:09:05
Y esto 00:09:07
Sobrecarga el programa 00:09:09
Crea más 00:09:11
O sea, lo hace más lento 00:09:12
Porque en un 99% 00:09:15
De las veces esto iría todo bien 00:09:17
Porque no es null y el valor es mayor que 0 00:09:19
Pero yo lo estoy comprobando igualmente 00:09:22
Cada vez, ¿vale? Serían estos if innecesarios. Y también, trabajando así, es bastante complejo identificar todos los posibles problemas. Y que este objeto podría ser nul, pero que este proyecto podría ser no nul, pero dentro tiene otra referencia a otro objeto y esa sea nul. 00:09:23
podría tener este valor que es mayor que 1 pero menor que 0 00:09:44
entonces, ¿me entendéis? 00:09:49
o sea, se necesita mucha experiencia y mucho control de todos los posibles errores 00:09:50
y cuando llegamos a sistemas muy complejos 00:09:55
pues que se me olvide alguno de estos tipos de controles es posible 00:09:59
entonces está el manejo de excepciones optimista 00:10:06
el manejo de excepciones optimista es un poco decir 00:10:09
cuando hay un trozo de código peligroso 00:10:11
que podría dar problemas 00:10:14
que podría hacer un acceso a null 00:10:15
que podría hacer un acceso fuera del array 00:10:17
pues tú ejecútalo 00:10:19
asumimos que no haya fallos 00:10:22
las veces que haya fallos 00:10:25
en vez de haberlo comprobado cada vez 00:10:28
hasta cuando no haya fallos para estar seguro 00:10:31
pues las veces que explotará 00:10:33
que dará problemas 00:10:35
pues allí te escribiré un trocito de código 00:10:36
para qué tienes que hacer cuando pasan estas cosas. 00:10:39
Y este es el try catch. 00:10:44
El try selecciona un trozo de código, esto se ejecutará. 00:10:46
Si va todo bien, el catch no sirve de nada. 00:10:51
Si dentro de este trozo de código pasa algún problema, 00:10:55
el catch podrá recuperar ese error y ejecutar un código que se ejecuta. 00:10:59
Tened en cuenta que el try no se ejecuta completamente. Si en la primera línea del try es donde surge el error, porque hago un null pointer exception y luego hay otras 10 líneas de código, estas otras 10 líneas de código no se han ejecutado. 00:11:06
En el momento en que se lanza la excepción, en el momento en que ocurre la excepción, pues se interrumpe el bloque try y se pasa al bloque catch. 00:11:21
Este de aquí podría ser uno muy genérico, porque cualquier excepción se pilla en el catch, luego veremos que podemos hilar un poquito más fino. 00:11:32
Es decir, si la excepción era esta, hace una cosa, pero si la excepción era esta otra, hace una cosa distinta. 00:11:41
dudas hasta aquí 00:11:46
entonces esto sería lo mismo 00:11:48
en versión 00:11:53
pesimista y optimista 00:11:55
¿vale? en versión pesimista por ejemplo 00:11:57
yo pillo dos números 00:11:59
num denominador y antes de hacer 00:12:01
num dividido den 00:12:04
¿vale? que sería una fracción 00:12:06
pues lo que hago es comprobar 00:12:07
que el denominador no sea cero 00:12:09
porque si divido por cero me daría un error aritmética 00:12:11
una excepción aritmética 00:12:14
una divided by zero 00:12:15
¿vale? 00:12:17
Entonces, cada vez que yo hago esta operación 00:12:18
Pasaré por este if 00:12:21
Y todas las veces que yo daré un then 00:12:22
Que no sea cero 00:12:26
Pues igualmente haré este if y lo comprobaré 00:12:27
¿Sí? Entonces 00:12:30
Si esto lo hago un millón de veces 00:12:30
Haré hecho un millón de veces este if 00:12:33
Independientemente que el then sea cero o no 00:12:34
La versión optimista 00:12:37
Es decir, yo esto lo guardo en un try-catch 00:12:39
Si por si acaso aquí salta una 00:12:42
Divide by zero exception 00:12:45
o ArithmeticException o lo que sea 00:12:46
pues lo recojo con esta excepción de aquí 00:12:48
te digo, oye mira, no es válido 00:12:51
hacer esto 00:12:52
y sigo adelante 00:12:54
si esto lo hago un millón de veces 00:12:55
pues a lo mejor esta parte de aquí 00:12:57
la ejecutaré unas cuantas veces 00:12:59
pocas veces 00:13:01
cuando hay una división por cero 00:13:02
tened en cuenta que igualmente 00:13:05
el try-catch no es gratis 00:13:06
o sea, marcar un trozo de código 00:13:08
y vigilarlo porque si explota 00:13:10
pues si yo pillo un catch 00:13:13
pues tendrá su coste computacional 00:13:14
pero técnicamente debería ser inferior 00:13:16
a hacer explícitamente un if 00:13:18
sobre todo si luego este if 00:13:20
es complejo, porque un if 00:13:22
facilita si está bien, si yo para 00:13:24
encontrarme den tengo que acceder a un 00:13:26
método, hacer una llamada de método, el método 00:13:28
hace una operación y de ahí saca un dato 00:13:30
y cuando este dato lo comparo a 00:13:32
otras cosas, pues puede ser más complejo 00:13:34
hacer este if que hacer simplemente un traquecho 00:13:36
¿Dudas? 00:13:39
Clase exception 00:13:44
Cuando hay una excepción 00:13:46
La Java Return Machine crea un objeto de la clase Exception 00:13:48
O sea, existe una clase 00:13:51
Todas las excepciones que hemos visto nosotros 00:13:52
ArrayIndexOutOfBoundException 00:13:55
IOException 00:13:58
NullPointerException 00:14:00
Todas son de una clase 00:14:02
Son heredan de una clase 00:14:05
Que se llama Exception 00:14:07
Exception luego heredará de otras cosas 00:14:09
Hasta llegar a Object 00:14:11
En este objeto se guarda la información relevante del error 00:14:13
Entonces, este es como un paquete de información 00:14:17
Que crea la Java Virtual Machine 00:14:21
Cuando hay un error en tiempo de ejecución 00:14:23
Diciendo, toda la información que puede ser relevante 00:14:25
Sobre este error, la empaqueto en un objeto 00:14:30
¿Quién ha producido el objeto? 00:14:33
¿Cuándo lo ha producido? 00:14:35
¿Qué ha causado el error? 00:14:37
¿En qué método se ha pasado eso? 00:14:40
etc, etc, etc, todo empaquetado 00:14:43
bonito para que yo luego lo recoja 00:14:45
sería esto 00:14:47
sería esto, veis que aquí 00:14:48
exception e, esto es como 00:14:57
poner int x 00:14:59
pues esto estoy creando una variable e 00:15:00
de tipo exception 00:15:03
que será un objeto 00:15:04
exception, y yo luego allí 00:15:06
podré hacer algo con este objeto, podré hacer 00:15:09
e.printstack 00:15:11
o e.getMessage 00:15:14
o e. 00:15:16
y todos los métodos que puedan haber 00:15:17
en esa excepción 00:15:18
o sea que 00:15:20
también aquí estamos usando 00:15:22
mucho el concepto de 00:15:24
herencia 00:15:27
¿vale? porque todos son excepciones 00:15:28
pero luego dentro veremos que hay 00:15:30
distintas, entonces si yo 00:15:32
uso una referencia de tipo exception 00:15:35
puedo utilizar los métodos de exception 00:15:36
pero si luego puedo hacer un downcasting 00:15:38
de esta excepción a otras excepciones 00:15:40
más pequeñas, más concretas 00:15:42
y utilizar los métodos de ellas 00:15:44
Un mismo código peligroso podría causar distintos tipos de excepciones 00:15:46
La Java Art Machine creará un objeto a su clase más apropiada 00:15:53
Si el error ha sido porque ha cedido fuera de un array 00:15:56
Será un array index out of bound 00:15:59
Si el error ha sido porque el array era null 00:16:01
Pues será una null pointer exception 00:16:04
Si es un error porque escribí en un fichero 00:16:06
El fichero no existe 00:16:08
Será una input out of exception 00:16:09
Una IO exception 00:16:11
entonces aquí 00:16:13
hay la numpointer exception 00:16:14
numperformate exception 00:16:16
ioexception, io mogollón 00:16:19
manejo de excepciones finos 00:16:20
es decir que cuando yo hago un catch 00:16:25
en vez de poner algo así grueso 00:16:26
de píllame una cualquier excepción 00:16:29
y allí hago algo 00:16:31
pues yo puedo decir 00:16:33
oye mira te voy a dar varios bloques catch 00:16:34
y este catch 00:16:37
lo usarás si es una input 00:16:39
autoexception, este catch 00:16:41
si es una RuntimeException 00:16:43
este de aquí si es 00:16:45
una NumberFormatException 00:16:47
de esta forma podría dar mensajes 00:16:49
distintos en base 00:16:51
a lo que ha explotado, si me dice 00:16:53
ArrayIndex.topBound te diré 00:16:54
oye mira has intentado acceder fuera 00:16:57
del array y por favor revisa 00:16:59
la posición, si en vez es un 00:17:01
NullPointerException te diré, oye mira el objeto 00:17:03
al que intentas acceder es null 00:17:05
y por lo tanto no puede acceder 00:17:07
en vez de dar siempre el mismo error de error 00:17:08
cuanto más 00:17:11
y lamos finos, luego es más fácil 00:17:12
para los administradores, para los desarrolladores 00:17:15
entender qué ha pasado 00:17:17
y por qué ha ido mal 00:17:19
y por qué ha habido problemas, ha habido errores 00:17:20
en este programa 00:17:23
adicionalmente existe 00:17:24
un cache especial 00:17:26
que es el bloque finally 00:17:29
que es un bloque que se ejecuta 00:17:30
siempre, tanto 00:17:32
que haya habido un error 00:17:34
como que no haya habido un error 00:17:36
siempre se ejecutan las líneas 00:17:38
dentro de finally 00:17:41
Por lo tanto, imaginémonos una cosa de ese estilo 00:17:42
Está el bloque 1, luego está un try, está el bloque 2 00:17:47
Luego está un catch de ArithmeticException, ArithmeticException 00:17:51
Bloque 3, ExceptionError, bloque 4 y bloque 5 00:17:55
¿Qué pasa si no hay excepciones? 00:18:01
Que se ejecuta el bloque 1, luego se ejecuta el bloque 2 00:18:03
Y al final se ejecuta el bloque 5 00:18:07
El bloque 3 y el bloque 4 nunca se ejecutarán porque no ha habido excepciones 00:18:10
¿Qué pasa si hay una excepción de tipo aritmético? 00:18:14
Si empieza el bloque 1, el bloque 2 se ejecuta pero solo parcialmente 00:18:17
Porque en un determinado momento de este bloque habrá un error aritmético 00:18:22
Cuando explota la aritmética exception, pues se ejecuta el bloque 3 00:18:26
Y cuando se acaba el bloque 3, se ejecutará el bloque 5 00:18:31
Se sigue después del bloque try-catch 00:18:35
O la pregunta, ¿dentro del bloque C podría haber otro try-catch? 00:18:37
Sí, tranquilamente 00:18:42
Que dentro de este de aquí, o sea, dentro de un catch 00:18:43
Podría poner un try-catch 00:18:47
La idea es que en un determinado momento 00:18:48
Debería intentar de hacer cosas y explotar 00:18:52
Debería recuperarme o acabar o cosa por el estilo 00:18:54
Pero si fuera necesario, imaginaos que yo intento escribir en un fichero 00:18:58
Y ese fichero no existe, me salta una IO exception 00:19:02
Pues aquí digo, vale, si no puedes escribir en el fichero que te han dicho 00:19:05
Crea tú un fichero por defecto y ahora intenta escribirlo allí 00:19:10
Y si me pasa otro error porque el disco duro está lleno 00:19:15
Entonces no puedo crear eso, pues allí habría otro try catch dentro del catch 00:19:18
¿Me explico? 00:19:21
Por ejemplo 00:19:23
Imaginamos que en vez de salte una null pointer exception 00:19:24
Pues ejecuta el primero y en el dos en un determinado momento hace una null pointer exception 00:19:29
dice es una aritmética excepción no por lo tanto este bloque no se ejecuta sería este de aquí que 00:19:33
es una excepción general pillaría todas las excepciones que no sean ésta por lo tanto se 00:19:39
ejecuta el bloque 4 y luego después el bloque 5 sí si le añadimos el final y vale sin excepciones 00:19:45
es bloque 1 hace el bloque trae completo luego después hace el final y luego después el bloque 5 00:19:54
si hay una excepción de tipo aritmético 00:20:01
lo que haría es el bloque 1 00:20:05
el bloque 2 a mitad 00:20:06
explota la aritmética exception 00:20:08
ejecuta el bloque 3 00:20:10
a este punto hace un finally 00:20:12
o sea ejecuta también lo que está en el bloque 4 00:20:14
y después sigue con el programa 00:20:17
después del track edge 00:20:18
si fuera una excepción de otro tipo 00:20:22
diferente 00:20:25
pues haría el bloque 1 00:20:26
luego el bloque 2 00:20:29
y explotaría 00:20:30
Haría el finally 00:20:31
Y luego posiblemente acabaría 00:20:33
Porque no se ha pillado 00:20:36
La excepción 00:20:38
Aquí no hay un catch 00:20:41
De exception 00:20:43
Por lo tanto el programa acabaría 00:20:44
Si yo la excepción no la recojo 00:20:46
El programa termina 00:20:47
Entonces no llegaría nunca al 5 00:20:49
Pero si el 4 00:20:51
El finally es como un 00:20:52
Una cosa final 00:20:57
Que haces 00:21:00
antes de decir ya está, aquí hemos llegado 00:21:01
pero si has pillado 00:21:04
el catch, la excepción 00:21:06
no ha llegado a la Java Virtual Machine 00:21:08
entonces no se ha bloqueado, entonces sigue adelante 00:21:09
entonces después de haber hecho el finally 00:21:12
sigo adelante, si en vez es una 00:21:13
excepción que no he manejado 00:21:16
y por lo tanto 00:21:18
ha subido hasta llegar a un momento en que 00:21:19
el programa se tiene que acabar 00:21:22
pero igualmente el finally se ejecuta porque por ejemplo 00:21:23
en ese momento tú guardas los datos importantes 00:21:26
en un fichero, escribes en pantalla 00:21:28
el resultado parcial actual para que 00:21:30
no se pierda todo y a ese punto 00:21:32
ya le dices a la máquina virtual haz lo tuyo 00:21:34
como el programador me ha dicho que 00:21:36
no tengo que recoger esta excepción 00:21:38
y por lo tanto 00:21:40
tiene que acabar, porque 00:21:41
si no recoges la excepción quiere decir que 00:21:44
quieres que se acabe allí 00:21:46
de forma bruta el programa 00:21:47
pero al menos esta parte finally 00:21:50
te ha permitido hacer una última pincelada 00:21:52
antes de 00:21:54
explotar 00:21:55
¿Vale? Se me ha 00:21:58
quejado Rosa de que 00:22:00
usáis la palabra explotar 00:22:02
como término técnico 00:22:03
en sus exámenes. 00:22:05
Por favor, explotar 00:22:08
no es técnico. 00:22:10
No, tampoco. 00:22:15
Que, extrañamente, son las cosas 00:22:20
que os quedan. Yo puedo estar 45 minutos 00:22:21
hablando de excepciones y 00:22:23
que es una excepción, nunca lo he oído. 00:22:25
Pero, exploto. Mira, hablamos de ti. 00:22:27
Pues nada, que 00:22:30
me paro, que es acabado. 00:22:31
Acabaremos el jueves 00:22:32
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Primer Curso
Autor/es:
Stefano Chiesa
Subido por:
Stefano C.
Licencia:
Reconocimiento - No comercial
Visualizaciones:
2
Fecha:
27 de febrero de 2025 - 12:48
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
22′ 35″
Relación de aspecto:
16:10 El estándar usado por los portátiles de 15,4" y algunos otros, es ancho como el 16:9.
Resolución:
1152x720 píxeles
Tamaño:
52.88 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid