20250505 EjerFichCSV_2 - Contenido educativo
Ajuste de pantallaEl ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:
Ya sabemos que la forma más cómoda siempre es un file chooser
00:00:00
y eso ya más o menos casi nos lo sabemos de memoria.
00:00:03
Que es instanciar el objeto.
00:00:07
Primero instanciamos el objeto.
00:00:15
Una vez que tenemos instanciado el objeto,
00:00:23
ahora ya tenemos que abrir el cuadro de diálogo.
00:00:27
Abrir el cuadro de diálogo se hacía con un método
00:00:30
que empezaría por show, digo yo,
00:00:33
open o save
00:00:37
pues depende si queremos
00:00:39
que aparezca open o save
00:00:41
en el botoncito, como en este caso es para abrir
00:00:43
pues open mejor
00:00:45
vale
00:00:46
esto le pasamos null
00:00:49
porque es la ventana padre
00:00:51
a la que va anclada, solo tenemos una
00:00:53
ventana padre, pues nada
00:00:55
y ahora esto nos devolvía
00:00:56
¿verdad? un numerito
00:01:01
entero que estaba
00:01:03
relacionado con la opción
00:01:07
que hubiera marcado el usuario en esa ventana
00:01:08
de diálogo, si había marcado open
00:01:10
o había marcado cancel
00:01:12
¿vale? entonces
00:01:14
ahora ya esa opción
00:01:16
podía ser
00:01:19
la de aprobar
00:01:20
entonces si la opción que han marcado
00:01:22
resulta que es
00:01:25
igual a
00:01:26
approve option, es porque ha dado la de open
00:01:27
y en este caso
00:01:32
ya podemos coger el nombre del fichero
00:01:34
¿vale? el nombre del fichero
00:01:36
el nombre del fichero
00:01:38
Lo tenemos que tener guardado
00:01:40
En algún sitio de ámbito global
00:01:44
Porque el resto de la aplicación
00:01:46
Va a trabajar con ese fichero
00:01:48
Para
00:01:50
Para abrirlo, para lo que sea
00:01:51
Entonces, ¿tenemos alguna variable para guardar ese fichero?
00:01:54
Pues no, todavía no
00:01:57
Todavía no
00:01:58
Pues venga, vamos a crearla
00:02:00
Aquí, por ejemplo
00:02:02
Bueno, podemos
00:02:03
Puede ser file, puede ser string
00:02:06
¿Vale? Nombre del fichero
00:02:09
csv, nombre del fichero csv
00:02:12
que vamos a abrir, bueno pues
00:02:15
el nombre del fichero csv que vamos a
00:02:16
abrir, ahora ya si que podemos
00:02:19
obtenerlo en este
00:02:20
momento
00:02:22
porque será
00:02:23
no lo he llamado así seguro, verdad
00:02:25
non-fich csv
00:02:33
será de mir file chooser
00:02:34
el get
00:02:43
bueno como me lo devuelve en file
00:02:49
pues efectivamente como me lo
00:02:53
devuelve en file, vamos a declararlo como file
00:02:55
y ya está
00:02:57
fichero csv
00:02:58
el objeto
00:03:06
file asociado a ese fichero
00:03:08
ya lo
00:03:09
tengo aquí
00:03:12
vale, ala
00:03:13
entonces, ese evento era
00:03:20
para abrir el objeto
00:03:22
file con el que vamos a trabajar
00:03:24
y luego ya la aplicación
00:03:26
tiene que hacer algo más este evento
00:03:29
pues en principio
00:03:35
no, me ha habilitado esa variable
00:03:37
y ahora con esa variable que ya está habilitada
00:03:38
global, accesible para todo el mundo
00:03:41
ahora yo ya puedo
00:03:43
hacer las opciones de serializar
00:03:44
que ahora ya sí que es
00:03:46
leer del fichero y construir los objetos
00:03:48
¿cierto? bueno pues este evento
00:03:50
ya no tiene nada más
00:03:52
podemos poner el nombre del fichero seleccionado
00:03:53
en una etiqueta debajo
00:03:56
pues que de hecho habíamos puesto una etiqueta ahí
00:03:58
para poner el nombre del fichero seleccionado
00:04:00
pues vamos a poner la etiqueta se llama
00:04:02
nombre fichero, pues entonces
00:04:04
que ese evento
00:04:06
eso, que ese evento
00:04:07
en nuestra etiqueta que se llamaba
00:04:12
se me ha olvidado como se llamaba
00:04:14
nombre fichero seguramente
00:04:16
punto
00:04:18
set test
00:04:22
y ahora
00:04:23
mi fichero que es este
00:04:25
como este es el objeto file
00:04:28
lo que queremos es una de las propiedades del objeto
00:04:33
file que es su nombre
00:04:35
pues lo sacamos con get name
00:04:37
por ejemplo
00:04:40
o con
00:04:42
depende si es lo que
00:04:44
queramos mostrar toda la ruta, vamos a poner get name
00:04:46
a ver que me saca
00:04:48
nombre fichero
00:04:49
lo tengo declarado aquí
00:04:52
debajo, entonces la vamos a subir arriba
00:04:54
y ya está
00:04:56
subida arriba
00:05:01
vale, pues ese evento ya está entero
00:05:03
está claro
00:05:05
¿no? recordad que en general
00:05:07
las clases internas, las clases anónimas
00:05:09
que son los eventos
00:05:12
sirven para cambiar valores
00:05:13
de variables que están
00:05:16
accesibles por parte
00:05:18
del resto de eventos
00:05:20
entonces yo tendré, siempre tengo que tener claro
00:05:21
con qué datos trabaja mi aplicación, esta aplicación
00:05:24
trabaja con un objeto file
00:05:26
bueno, pues objeto file
00:05:28
lo declaro en espacio global para cualquiera
00:05:29
de las clases anónimas, puedo trabajar con él
00:05:32
bueno, pues ahora ya serializar
00:05:33
tendrá
00:05:36
una respuesta a evento
00:05:38
y va a necesitar
00:05:40
ese objeto file.
00:05:42
Bueno, pues, ¿qué tiene que hacer este?
00:05:44
Tiene que,
00:05:45
de ese CSV, que se supone que tiene esta estructura,
00:05:48
tiene que construir
00:05:51
un objeto
00:05:52
persona
00:05:54
por cada línea.
00:05:55
¿Vale?
00:05:58
Y luego ya esos objetos persona
00:05:59
guardarlos en un fichero.
00:06:01
Luego la clase persona nos falta.
00:06:02
Para hacer objetos persona necesitamos una clase persona.
00:06:05
Pues, ala, vamos a hacer una clase Persona.
00:06:08
Y esta clase Persona tiene como propiedades nombre NIF y lista de teléfonos.
00:06:21
Como la lista de teléfonos tiene longitud variable, pues necesitamos que sea un list, ¿vale?
00:06:28
o un array o un conjunto
00:06:36
podría ser un conjunto porque los teléfonos
00:06:38
suponen que no se repiten
00:06:40
entonces como los teléfonos no se repiten
00:06:41
vamos a poner un conjunto
00:06:44
y de hecho vamos a poner
00:06:45
hasta un triset para que
00:06:48
si esta aplicación me manda
00:06:50
listados del listado de teléfonos
00:06:52
pues bueno, ya que por orden
00:06:54
¿para qué quiere uno por orden?
00:06:55
pues ya que alguien que sea muy maniático
00:06:57
por ejemplo
00:06:59
mi zona era 9138
00:07:01
mi zona era 9138
00:07:03
Bueno, por si acaso tuvieron interés
00:07:05
Pues ya está
00:07:10
Pues hala
00:07:11
El nombre
00:07:12
Y el NIF
00:07:15
Sabías donde vivía
00:07:17
El colega
00:07:22
Vale
00:07:24
Y ahora esto va a ser un
00:07:26
Un conjunto
00:07:27
De números de teléfono
00:07:30
Los números de teléfono
00:07:32
Podríamos guardarlo como ínteger
00:07:34
Pero es que es un ínteger tan feo y tan largo
00:07:36
Que
00:07:38
Por ejemplo, pero si tienen el más
00:07:40
Al guardarlo como string
00:07:48
Lo va a ordenar en orden alfabético
00:07:50
Que como es el de cifras, pero si pones un más
00:07:51
Ya te va a cambiar
00:07:54
Pero bueno, como nos gustan los trisets
00:07:56
Y queremos ver las cosas ordenadas
00:07:58
Según en este caso la tabla ASTI
00:08:00
Al guardarlo como string lo va a ordenar
00:08:02
como caracteres así, pues vamos
00:08:04
a hacer un
00:08:06
¿Os parece bien, no?
00:08:07
Un triset de teléfonos.
00:08:10
Porque nos gusta innovar.
00:08:12
Vale.
00:08:14
Si no pongo el new,
00:08:30
vale.
00:08:38
Entonces, recordad que esta estructura
00:08:40
respecto
00:08:42
a los sets
00:08:43
siempre son mejores que las listas
00:08:46
computacionalmente, está claro. Porque no tienen que
00:08:48
gestionar el tema de las posiciones
00:08:50
problema que no admiten
00:08:52
duplicados, eso ya lo sabemos
00:08:55
no se puede repetir un elemento
00:08:56
varias veces en el conjunto
00:08:58
si no necesitamos
00:09:00
duplicados como es este caso
00:09:03
porque los teléfonos van a repetir un conjunto
00:09:04
dentro de las alternativas
00:09:06
has set, tree set
00:09:08
si vamos a generar listados
00:09:10
ordenados, el orden de los elementos
00:09:12
nos importa porque vamos a iterar
00:09:15
y vamos a mostrar
00:09:17
y nos viene muy bien que nos muestre por orden
00:09:18
pues un triset, en principio no habría
00:09:20
otra razón para elegir un triset
00:09:22
que no fuera que los elementos
00:09:24
en algún momento voy a iterar por ellos
00:09:26
y me va a venir bien que aparezcan por orden
00:09:28
en este caso
00:09:30
¿qué orden va a ser? repito, pues
00:09:32
el orden que esté establecido entre
00:09:34
los string, y entre los string
00:09:36
el orden no lo decidimos nosotros
00:09:38
está ya establecido como
00:09:40
el alfabético
00:09:42
si nosotros dijéramos
00:09:43
oye, quiero ordenar
00:09:48
los números, quiero tener números de teléfono
00:09:50
quiero que estén ordenados
00:09:52
pero no quiero el orden alfabético
00:09:54
quiero otro orden
00:09:56
¿qué solución
00:09:57
adoptaríais?
00:10:00
porque no podéis meteros en la clase
00:10:01
string, a la clase string de la máquina
00:10:04
virtual uno no puede meterse, cambiar
00:10:06
el compare to porque se le ha puesto
00:10:08
recompilarlo y volverlo a meter en la
00:10:10
JRE, eso jamás lo haríamos
00:10:12
y si no hacemos eso
00:10:14
el triset va a iterar siempre el orden
00:10:17
del string que sea alfabético
00:10:20
pero a nosotros no nos interesa que el orden sea alfabético
00:10:21
nos interesa otro
00:10:24
¿qué solución podríamos incorporar aquí?
00:10:25
un comparator
00:10:28
instanciar
00:10:30
el triset
00:10:32
con un objeto comparador
00:10:32
¿vale?
00:10:35
pero tendríamos que hacer
00:10:38
un objeto comparador
00:10:42
el criterio de comparación que fuera
00:10:44
comparador
00:10:46
¿eh?
00:10:48
14.000 criterios
00:10:50
bueno, si yo lo llamo como quiera, la clase
00:10:51
entonces
00:10:54
me tendría que crear esta clase
00:10:56
de tal forma
00:10:58
que fuera un criterio de comparación
00:11:00
y para que fuera un criterio
00:11:02
de comparación
00:11:04
tiene que implementar
00:11:05
esto
00:11:07
entonces
00:11:09
ahora, aquí ya
00:11:11
me invento yo
00:11:18
el criterio de ordenación de string
00:11:19
que me dé la gana
00:11:22
el criterio de ordenación de string que me dé la gana
00:11:23
porque no me gusta el alfabético
00:11:26
el que quisiéramos
00:11:28
¿qué otro criterio de ordenación
00:11:30
de string?
00:11:32
por ejemplo
00:11:35
el alfabético inverso
00:11:36
nos apetece
00:11:37
que nos itere en alfabético inverso
00:11:38
claro
00:11:42
pues cambiar el signo
00:11:45
a lo que me devolvería el otro
00:11:47
podríamos hacer
00:11:49
return
00:11:51
O1, que es el primer string
00:11:53
compare tú O2
00:11:56
pero esto cambiado de signo
00:11:58
vale, ya está
00:12:02
me acabo de hacer
00:12:07
el alfabético inverso
00:12:09
un crítico de ordenación alfabético inverso
00:12:10
porque este es el alfabético normal
00:12:13
entre O1 y O2
00:12:15
le multiplico por menos 1
00:12:16
pues alfabético inverso
00:12:18
si comparas el O2 con dentro del O1 ya te lo haces
00:12:20
sí, efectivamente
00:12:22
también, pongo el o2 antes que el o1
00:12:25
claro, efectivamente
00:12:28
vale, pero bueno
00:12:29
no viene mal que recordemos que como funciona
00:12:32
es, te va a devolver
00:12:34
uno si este va
00:12:36
antes de este otro
00:12:38
cero si son el mismo
00:12:39
y menos uno, perdón
00:12:41
te devuelve negativo
00:12:43
si este va antes
00:12:45
cero si son el mismo
00:12:47
y positivo si este va después
00:12:49
entonces o1 compare tu o2
00:12:51
te va a devolver menos 1 si este va antes
00:12:54
como yo quiero que el orden sea el inverso
00:12:56
multiplico por menos 1 para que me dé 1 y ya está
00:12:58
bueno, pues
00:13:00
¿vale? entonces
00:13:02
de esta manera
00:13:03
conseguimos que
00:13:05
para este triset
00:13:07
cuando él vaya metiendo los teléfonos
00:13:10
los vaya metiendo
00:13:12
en el orden que fija este
00:13:14
en el orden que fija este
00:13:15
no en el orden que fija el comparable de string
00:13:17
es lo que conseguimos
00:13:19
¿vale?
00:13:21
solamente a efectos del triset
00:13:23
solo a efectos del triset lo va a ordenar
00:13:25
en función de este criterio
00:13:27
bueno, pues vamos a incorporarlo ahí
00:13:29
aunque sea una tontería, como no molesta
00:13:32
lo dejamos ahí, pues nuestra clase persona
00:13:34
tiene estas tres propiedades
00:13:36
y ahora le ponemos los get y los set
00:13:37
y por vaguería
00:13:40
dejamos
00:13:45
dejamos
00:13:47
los constructores
00:13:49
para ponerlos si nos van viniendo bien
00:13:51
por vaguería
00:13:54
venga, pues ahora
00:13:54
estábamos haciendo
00:13:56
el evento
00:13:59
de este de aquí, de serializar
00:14:00
este evento
00:14:03
bueno, ¿este qué tiene que hacer?
00:14:04
abrir el fichero
00:14:07
que es de texto
00:14:09
leer línea por línea
00:14:09
con lo cual ahí ya automáticamente pensamos
00:14:12
un buffer reader
00:14:15
que me lee línea por línea de golpe
00:14:16
con cada línea
00:14:18
hago un split
00:14:20
de los elementos
00:14:22
y con esos elementos construyo
00:14:24
el objeto persona
00:14:26
y lo mando al fichero
00:14:26
de objetos serializados
00:14:29
pues venga
00:14:31
vamos a hacerlo por partes
00:14:33
instanciamos un buffered reader
00:14:35
que el buffered reader
00:14:37
siempre va asociado a un file reader
00:14:49
que a su vez va asociado al objeto file
00:14:51
y este
00:14:53
puede que me de la excepción
00:15:12
de que el fichero no existe
00:15:14
pues la capturo
00:15:15
entonces
00:15:18
capturo la excepción
00:15:29
y
00:15:32
si el fichero no existe
00:15:38
no hay nada que serializar
00:15:40
entonces aprovechando que se ha ido rosa
00:15:41
pues ponemos el return aquí
00:15:44
porque ya no hay más que hacer
00:15:45
si el fichero no existe no hay nada que serializar
00:15:46
el evento no tiene nada más que hacer
00:15:49
return
00:15:51
la referencia de buffer errader
00:15:51
vamos a ponerla aquí fuera
00:15:55
bueno
00:15:58
si hemos llegado a este punto
00:16:05
si hemos llegado a este punto después del catch
00:16:07
es porque hemos abierto el bafle real
00:16:12
ahora que nos toca hacer
00:16:13
ir leyendo línea por línea
00:16:15
bucle de lectura por líneas
00:16:17
que no es lo mismo
00:16:19
que bucle de lectura por caracteres
00:16:22
por caracteres habríamos abierto con el file real
00:16:23
venga pues
00:16:25
el bucle de lectura por líneas
00:16:27
me permite ir leyendo
00:16:29
de línea a línea
00:16:31
y ahora mientras cada línea
00:16:32
siendo cada línea
00:16:36
igual aquí
00:16:38
al resultado de leer esto
00:16:38
sea diferente de null
00:16:41
es decir, todavía tengo líneas
00:16:44
que leer
00:16:46
pues entonces, ¿qué es lo que tenemos que hacer?
00:16:46
esto de nuevo puede que me salga
00:16:50
¿por qué sales?
00:16:52
buenas tardes
00:16:56
¿cómo se cierra esta cosa?
00:16:57
este puede que me dé excepción
00:17:10
la capturo
00:17:22
bueno pues que hacemos dentro del bucle de lectura
00:17:23
tenemos que hacer un split
00:17:29
lo primero de todo para tener los datos
00:17:31
los datos van a ser
00:17:33
un array de objetos string
00:17:36
entonces
00:17:38
línea punto split
00:17:41
y split en torno a qué carácter
00:17:44
en torno al carácter punto y coma
00:17:48
y ahora
00:17:50
construimos un objeto persona con los datos
00:17:53
pues ya está
00:17:56
persona p
00:17:57
igual a
00:18:01
vale
00:18:12
el nombre ya lo tenemos
00:18:12
porque el nombre será el primero de los datos
00:18:14
datos de cero
00:18:17
el nif
00:18:20
también lo tenemos
00:18:22
porque será el segundo
00:18:24
datos de uno
00:18:25
y nos faltan los teléfonos
00:18:27
para eso hay que construir un set
00:18:30
con todos los teléfonos
00:18:32
entonces pues podemos hacer
00:18:34
tranquilamente un
00:18:36
Sí, pero estoy pensando, ¿no?
00:18:48
Añadirlo directamente a...
00:18:50
¡Qué tontería!
00:18:53
Se lo vamos añadiendo a este.
00:18:54
A P...
00:18:55
No tengo que crearlo aquí.
00:18:57
Para cada dato.
00:18:59
Bueno, no.
00:19:04
Vamos a recorrer el array para todas las posiciones.
00:19:05
Uno, dos.
00:19:08
Desde la dos.
00:19:09
Desde la dos.
00:19:11
Bien.
00:19:12
Vale, pues ¿qué hacemos con cada uno de esos datos?
00:19:22
se lo añadimos a este, a teléfonos.
00:19:24
Datos de I, ya está.
00:19:34
Bueno, pues ya tenemos el objeto persona construido
00:19:39
con su nombre, que es el primero de los datos del split.
00:19:42
Su NIF, que es el segundo de los datos del split.
00:19:48
Y ahora, para el resto de los datos del split,
00:19:51
que no sé en los que son, desde el 2 en adelante,
00:19:53
los que sean, desde el 2 en adelante
00:19:55
los voy añadiendo
00:19:57
a la propiedad teléfonos
00:19:59
importante
00:20:02
haberla inicializado aquí ya
00:20:06
porque si no
00:20:07
al añadir el primer teléfono me saldría un null pointer
00:20:10
exception, lógicamente
00:20:12
entonces como la he inicializado aquí ya
00:20:13
no me sale un null pointer exception cuando añado
00:20:15
el primero de los teléfonos
00:20:18
bueno, pues ya
00:20:19
tenemos la persona y ahora hay que
00:20:22
pasarla a un fichero de objetos
00:20:24
entonces
00:20:25
vamos a abrirnos
00:20:27
el fichero de objetos
00:20:30
serializados
00:20:32
en ningún momento me dice
00:20:34
un nombre concreto y nada
00:20:36
al que a mi me de la gana
00:20:40
pues venga lo vamos a
00:20:41
crear el fichero de objetos
00:20:43
lo podemos directamente
00:20:45
crear aquí
00:20:48
un data
00:20:49
object
00:20:52
stream
00:20:53
object, perdón
00:20:58
object output string
00:21:04
el resultado final que querías que leyésemos
00:21:05
lo que es el archivo serializado
00:21:08
el archivo de objetos
00:21:09
que lo cargásemos y que leyésemos las personas
00:21:10
que cargases el fichero de objetos
00:21:13
para leer las personas
00:21:16
leer el archivo así sin más
00:21:17
que mostrarte el texto
00:21:20
no tenía mucho sentido
00:21:22
leer de objetos a ver si se ha construido bien
00:21:22
etc
00:21:26
Vale, pues
00:21:26
Sobrecomplicando las cosas
00:21:30
Claro
00:21:32
Pues por ejemplo, ¿cuál?
00:21:34
Personas
00:21:43
Punto
00:21:44
Dat
00:21:46
Ala
00:21:47
Pues ya hemos creado
00:21:53
Un object output stream
00:21:55
para escribir archivos, perdón, objetos.
00:21:57
El objeto outputString va siempre asociado
00:22:01
a un file outputString.
00:22:03
Y el file outputString ahora ya va asociado
00:22:05
al fichero que sea.
00:22:08
Y esto de nuevo, como puede tener una excepción,
00:22:11
pues trae cache.
00:22:16
Vale.
00:22:16
Lo declaramos fuera.
00:22:22
Eso, tiempo del examen
00:22:27
Un segundito
00:22:32
Un segundo
00:22:34
Vamos a acabar esto que es media línea
00:22:35
Vale, entonces
00:22:37
Hemos instanciado este fichero de objetos
00:22:40
Porque luego vamos a ir escribiendo en él
00:22:42
Si tiene un error
00:22:44
De
00:22:49
File not found exception
00:22:49
No se para que sale ese error
00:22:52
Pero bueno, vamos a poner retune
00:22:54
Claro, se lo voy a pasar ahora
00:22:55
No, ese es para verificar
00:23:06
El fichero
00:23:10
Serializar
00:23:12
Serializar y comprobar
00:23:17
Este es el que lo hace todo
00:23:19
Te saca del de texto y te lo guarda en archivo
00:23:21
Si era el de archivo, el de objetos
00:23:23
Y este es para volver a abrir el de objetos
00:23:24
Para asegurarse de que está
00:23:27
¿Vale?
00:23:28
Entonces
00:23:32
Tenemos
00:23:33
Hemos abierto el fichero de objetos
00:23:36
Para escribir en él
00:23:39
Asociado a este nombrecito
00:23:40
Si me da algún error
00:23:42
Retún, para que no haga nada más
00:23:45
Todo retún
00:23:47
Ahora estaba leyendo las líneas
00:23:47
Vale
00:23:51
Y ahora ya
00:23:55
Para cada línea
00:23:58
Construyo el objeto
00:24:00
Y una vez construido el objeto
00:24:01
Lo puedo escribir aquí
00:24:03
Objetos.
00:24:05
Objetos.
00:24:09
Write object
00:24:11
B
00:24:12
Vale, entonces
00:24:16
este bucle es el que lee la línea
00:24:20
la separa, construye la persona
00:24:22
y al fichero, lee la siguiente
00:24:24
la separa, construye la persona y al fichero
00:24:26
así todo el rato
00:24:28
cuando esto ya ha terminado
00:24:29
si hubiera una excepción, me piro
00:24:31
y cuando esto ya ha terminado, cuando estamos en este punto
00:24:34
cerramos los flujos
00:24:38
que los flujos
00:24:40
el buffer real se llamaba
00:24:42
br
00:24:44
close y el otro se llamaba
00:24:44
Objetos, Close
00:24:48
Y de nuevo esto puede sacar una excepción
00:24:50
Pero bueno, como estamos en modo examen
00:24:55
Quiero seguir improvisando
00:25:00
Pero si esto luego se puede dejar más bonito
00:25:01
Y no hacer tanto traicacho
00:25:04
Bueno
00:25:05
Este
00:25:08
Esto es Retour, no le gusta
00:25:11
Porque claro, no estoy cerrándolo en ese momento
00:25:14
Pero como no me va a seguir una excepción
00:25:17
Vale
00:25:19
Y aquí esto se me queda...
00:25:21
Ah, bueno, este de aquí.
00:25:23
Este sí que lo voy a meter aquí.
00:25:25
Esto ya es demasiado.
00:25:27
Separar.
00:25:29
Y ya está. Vale, vamos a parar aquí
00:25:34
antes de comprobarlo.
00:25:36
Un segundinín.
00:25:38
Un momentito.
00:25:40
- Materias:
- Programación
- Niveles educativos:
- ▼ Mostrar / ocultar niveles
- Formación Profesional
- Ciclo formativo de grado superior
- Primer Curso
- Subido por:
- Raquel G.
- Licencia:
- Todos los derechos reservados
- Visualizaciones:
- 21
- Fecha:
- 7 de mayo de 2025 - 19:33
- Visibilidad:
- Clave
- Centro:
- IES ROSA CHACEL
- Duración:
- 25′ 42″
- Relación de aspecto:
- 1.78:1
- Resolución:
- 1920x1080 píxeles
- Tamaño:
- 116.74 MBytes