DAVID: Muy bien, esto es CS50 y comenzamos la lección 10.
Demos la bienvenida a los padres que están con nosotros.
Si nos sintonizan en línea, este es el fin de semana familiar para los novatos.
Tenemos bastantes invitados con nosotros y
creemos que podríamos comenzar poniéndonos
cómodos, pues sé que quizás, esta es la primera vez en mucho tiempo
que han estado en la universidad.
Tal vez este es su primer curso para el semestre de otoño.
Y creemos que deberíamos compartir con ustedes
un pequeño video que muestre cómo deben sentirse
y que el equipo de video de CS50 preparó con ayuda de un pequeño amigo
hace algunos semestres.
[INICIO DEL VIDEO]
[MÚSICA DE FONDO]
- Hola.
- Hola
[FIN DEL VIDEO]
DAVID: Y bueno, bienvenidos a Harvard y a CS50.
En caso de que deseen regresar dentro de algunas semanas,
sus hijos, hermanos o amigos que están en esta sala
exhibirán sus proyectos finales de CS50, dentro de algunas semanas,
en la famosa feria de CS50, en la cual se pretende
exponer los proyectos finales de los alumnos del campus.
Y vale la pena resaltar, como ya saben los estudiantes del curso, que
el 68 % de ellos en el CS50 de este año, no tenía experiencia previa en CS.
De modo que, lo que ustedes y ellos verán exhibido en la feria de CS
dentro de unas semanas, en diciembre, serán todos sus éxitos.
De hecho, el objetivo de este evento
es deleitarse con lo que han logrado y dar un vistazo
a las pantallas y teléfonos de los demás, para comprobar con sorpresa el modo
en que cada uno de nuestros estudiantes se ha superado.
Ustedes también están invitados a presenciarlo, si así lo desean.
Ahora, el CS50 se caracteriza por ser un curso
para aquellos que no se sienten cómodos, para aquellos que sí se sienten cómodos
y para los que están en algún punto intermedio.
Me atrevería a decir que algunos de nuestros invitados de seguro se encuentran
en un extremo de esa escala o en el otro.
Tengan la seguridad de que hoy nos adentraremos en el mundo
de las bases de datos y de SQL, con aplicaciones a la ciencia de los datos
y mucho más, que sin duda es nuevo para la mayoría.
Pero se encuentran buenas manos, y me atrevo a decir que el 68 % o más
de los padres que están en la sala, se sienten exactamente igual que ustedes.
Entonces, si volvemos nuestra atención hacia algunas cosas de menor nivel,
aquellos que son alumnos, recordarán que en días pasados nos enfocamos
en Python, este otro lenguaje de alto nivel, por medio del cual
podemos resolver problemas más fácilmente que si utilizáramos algo de
menor nivel, como C. De seguro notaron que estoy listo para que nos adentremos
en la serie de problemas 6, la cual seguro ya tienen, pero el depurador 50 solo
es compatible con C y no con Python.
De modo que, relativamente, disponen de pocas herramientas para la depuración.
Pero noten que dentro de la biblioteca de CS50 para Python
hay una función como esta, llamada eprint, la cual
es posible que recuerden si ya utilizaron eprintf en C.
Esta es la misma versión pero en Python.
Y si necesitan ayuda para depurar sus programas,
basta con que los escriban en Python.
Y siempre que deseen ver un mensaje de diagnóstico,
simplemente recurran a la función eprint.
Esta imprimirá el nombre del archivo y el número de línea para la cual
escribieron dicha línea de código.
Pero, ahora centremos nuestra atención en cosas más orientadas a la web
y con las que seguramente están familiarizados, como Facebook
y su pantalla inicio de sesión.
Actualmente existen tantos sitios web que, cuando los visitamos,
nos piden que iniciemos sesión, es algo como esto.
Pero no nos solicitan que iniciemos sesión cada vez que entramos en facebook.com.
Tampoco se nos pide que iniciemos sesión cada uno o dos minutos
porque de hecho, en caso de ser necesario, los sitios web,
relegarán esta solicitud hasta que ya no sea necesario utilizarla.
Pero, de algún modo los sitios web recuerdan que ustedes ya iniciaron sesión.
De modo que, solo deben iniciar sesión una vez por día, por semana o por año.
Esto varía según el sitio web.
Y de alguna manera, el sitio web también recuerda que somos María o Brian,
y que ya hemos ingresado antes en este sitio web.
¿Pero cómo funciona eso?
¿Cómo es que Facebook o sitios similares, Gmail y muchos otros
recuerdan que ya hemos iniciado sesión o que ya ingresamos, aunque solo
escribimos nuestro nombre de usuario y contraseña una vez?
PÚBLICO: [INAUDIBLE]
DAVID: OK, ellos almacenan la información en un servidor.
Eso es exactamente lo que ocurre.
En el servidor, como lo vimos en Python y ahora con SQL,
tenemos la capacidad de almacenar información en él.
Hace una semana, vimos de manera muy sencilla la posibilidad de almacenar datos
en archivos CSV, que solo son archivos de texto en el servidor.
Estos no tendrán un rendimiento muy alto,
de modo que hoy, haremos algo mejor que eso.
También se pueden almacenar datos en forma de variables dentro de una Flask
mientras esta se ejecuta, como vimos antes.
Pero necesitaremos algo más sofisticado que eso.
Ciertamente, podemos recordar que María o Brian ingresaron.
Pero, ¿cómo recordamos desde cual computadora o navegador
ingresaron María o Brian?
PÚBLICO: [INAUDIBLE]
DAVID: Por la dirección IP, eso podría funcionar.
Puede que lo recuerden a partir de esos sobres virtuales
las cuales, ya no dispongo.
Hemos escrito las direcciones IP, en los lugares "de" y "para", en estas
sobres.
Y seguramente recordaríamos, oh, vi a Brian en 1.2.3.4, y a María
en 4.5.6.7 o cualesquiera que sean los números.
Pero ese es un problema en los hogares y sinceramente, incluso
últimamente en los campus debido a la NAT o traducción de direcciones de red,
esa técnica mediante la cual, muchos de los que estamos en esta sala
compartimos la misma dirección IP en nuestras laptops o teléfonos, al menos
con respecto al mundo exterior.
Y podríamos confundir las cosas.
Eso es malo porque significaría que si Brian se conecta a Facebook
y María también inicia sesión en Facebook, de repente Brian
podría ver la página de perfil de María o algo por el estilo.
¿Qué más podrían hacer?
¿Qué es eso?
PÚBLICO: ¿Una cookie?
DAVID: Una cookie, entonces.. eh, respuesta correcta, ¿pero qué
significa eso para el mundo?
PÚBLICO: [INAUDIBLE]
DAVID: ¿No lo saben?
OK.
Perfecto, entonces están en el lugar correcto.
Si utilizan la web con frecuencia, seguramente, casi todos en esta sala
escucharon acerca de las cookies y que éstas pueden ser peligrosas o malas
en cierto modo, quizás buscaron en Google cómo
cómo borrar sus cookies si, de hecho, también escucharon que son
malas o algo parecido.
De hecho, las cookies son la respuesta a esta pregunta.
Pero, ¿cómo funcionan realmente?
Bueno, si estuvieron antes en un parque de diversiones o en un club,
o en algún lugar donde normalmente accedemos con un boleto,
si queremos ir y venir desde el estacionamiento, hacia la calle
o a donde sea, puede que nos marquen la mano con un pequeño sello rojo,
un sello invisible o algo similar.
Y lo mostramos al guardia o a la persona que inspecciona
para que sepa que estuvimos allí antes, porque tenemos el sello
en la mano para que nos recuerden.
Los servidores web y los navegadores son algo parecido.
Cuando visitamos Facebook, Gmail o lo que sea por primera vez
y además iniciamos sesión, ellos ponen una especie de sello en la mano
digital en nuestro navegador llamado cookie.
Resulta que esa señal en la mano se implementó
obviamente no con tinta, sino como un gran número aleatorio que
se nos proporciona.
Y está almacenado ya sea en el RAM
o por largo tiempo, en el disco duro de nuestra computadora.
Y en nuestro navegador, porque éste habla HTTP,
ese protocolo del que hablamos, y que
fue diseñado para que mostremos la mano, por decirlo así.
Cada vez que revisan Facebook, o hacen clic en un correo electrónico,
o envían un mensaje, cada vez que naveguen por el mismo sitio web,
sin que se percaten de ello, el navegador le recuerda
al servidor, de ese sello en la mano.
Pero, ¿cómo puede hacerlo?
¿Dónde puede un navegador almacenar información como esta, de modo
que siempre esté en ese sobre?
Sí.
PÚBLICO: Puede colocarlo en una lista como la que hicimos con las invitaciones
o hacer algo similar.
DAVID: Las invitaciones, las invitaciones,
oh, eso sería de un menor niv.. OK, ahora recuerdo.
Eso no estaría del todo allí, porque queremos
asegurarnos de que esto básicamente, no tiene nada que ver
con nuestra aplicación.
Esto tiene relación con el HTTP.
Esto se inventó hace años, antes de que hubiera una lista de personas inscritas
para [INAUDIBLE].
Entonces no podemos colocarlo ahí.
Sí.
PÚBLICO: [INAUDIBLE]
DAVID: El concepto de un caché, aquí no, no, no.
Sí.
PÚBLICO: [INAUDIBLE] encabezado.
DAVID: El encabezado, el encabezado es
donde accedemos a los metadatos, ordenamos información técnica de nivel inferior
que la mayoría de nosotros nunca ve, a menos que escudriñemos en Chrome
o en realidad, husmeemos en nuestro tráfico de internet y lo veamos.
Pero dentro de los encabezados HTP existe la capacidad de enviar, por decirlo así,
este sello virtual.
Recordemos cómo se ven estos encabezados.
Los encabezados que se envían con este sobre virtual
por ejemplo, cuando solicitamos la página de inicio de Facebook,
podría verse así, con una diagonal, que da la orden de ir a la página de inicio,
utilizando la versión 1.1.
Solo como un recordatorio, el host que estoy visitando,
es: facebook.com o www.facebook.com.
Y debajo de eso quizás existan más encabezados.
En general, renunciamos a nuestras manos ahora no son tan interesantes
pero allí también puede haber un poco más de información.
Cuando Facebook responde, en especial después de que hemos
iniciado sesión, nos muestra alguno de los encabezados que hayamos visto
adicionales a los que sí vimos, la respuesta,
el 200 OK del servidor, es que Facebook y los servidores
como este, quizás también enviaron este encabezado, literalmente
Set-Cookie, dos puntos, después un nombre, un valor o clave y un value.
El nombre aquí, por ejemplo, comenzaré a llamarlo session,
ya que es un término especializado.
Y el value a la derecha puede, de hecho, ser cualquier cosa.
El valor podría ser 123, 456, o cualquier valor único
que sea generado al azar por el servidor, para recordar quiénes somos.
El valor de la sesión es igual al que está en nuestra mano y este es su valor.
Ahora, esa es la cookie que se colocó en la computadora, después
de eso, se supone que su navegador no enviará un conjunto de cookies.
Eso solo proviene del servidor al navegador.
Siempre que estamos en Facebook, visitamos otra página,
al hacer clic en el perfil de un amigo o algo similar,
su sobre virtual no puede contener estos encabezados familiares,
también la sesión cookie tiene un valor equivalente.
Esa es la presentación de ese mismo par de valores clave.
Con respecto al punto anterior, si Facebook recuerda que ese
usuario 123456 inició sesión y ese usuario se llama María
y podemos almacenar esa información en el servidor,
cada vez que Facebook ve este mismo sello de mano
o esta misma sesión de valor equivalente, será como, ¡oh, esa debe ser María!
Y entonces le mostraré a María sus mensajes y su página de perfil
y todo lo que se encuentra en su sitio web.
Demos un paso atrás porque el mecanismo es relativamente
tan simple como esto, aunque es ciertamente misterioso
y tienen que saber qué tipo de cosas se hacen para aprovechar esto.
Pero, ¿hay alguna amenaza aquí?
¿Por qué las cookies podrían ser peligrosas y por qué la gente
ocasionalmente las elimina?
PÚBLICO: si alguien obtiene acceso a [INAUDIBLE]..
DAVID: Sí, si alguien más obtiene acceso a sus cookies
podría hacerse pasar por María.
En el equivalente a un club o una parte, sería
como hacer algo con la mano de otra persona y tratar de decir, hey
los dos estamos aquí, aunque uno ahora está al revés, eso sería
un tipo de duplicación del valor de la sesión.
Probablemente quieran hacerlas seguras y que estén encriptadas.
¿Y cuál es la forma más fácil de asegurar que el tráfico entre ustedes
y un servidor que está encriptado?
PÚBLICO: [INAUDIBLE]
DAVID: No es necesario que sea deliberado.
PÚBLICO: SSL.
DAVID: SSL o el URL con el prefijo HTTPS.
Afortunadamente, la historia ha cambiado con los años,
y los servidores web están mejorando
en el soporte de HTTPS porque todas estas cosas,
incluso el navegador y el servidor pueden verlo,
al menos están encriptados o revueltos con cualquiera
que espíe y trate de ver qué está pasando entre los dos.
Pero hubo errores a lo largo de estas líneas.
De hecho, hace algunos años en CS50
dónde solo días u horas antes, un investigador de seguridad
presentó en una conferencia algún software muy fácil de usar
con el cual se podrían secuestrar las sesiones de otras personas,
o secuestro de sesión, que es el término artístico aquí.
Lo que él había implementado era este complemento para Firefox, otro navegador.
Eso permitiría, que cuando se ejecutara el complemento de este sujeto
simplemente olfatearía en todo el tráfico inalámbrico en la misma habitación.
Fácilmente nos mostraría, una lista de todas cookies en cada sesión
que estuvieron yendo y viniendo por el aire, por así decirlo,
y que no fueron encriptadas.
Esto fue, no sé, hace cuatro o cinco años atrás.
Cuando HTTPS existió, simplemente no había muchos sitios web,
que realmente lo usaron.
Así que muchos sitios web muy populares no lo usaron.
Así que, la demostración en el curso, afortunadamente no
pudo hacer más porque la mayoría los sitios web eran más seguros,
fue tan fácil para mí como hacer clic en un botón
para iniciar sesión en la cuenta de Rose porque ella usaba Facebook
durante la lección y sin el conocimiento de ella, hasta ahora.
Fue simplemente cuestión de capturar este tipo de valor.
Por otra parte, si las cookies de sesión, así se les llamó, se almacenaron
en el disco duro de su computadora, quedaron más vestigios
de donde han estado en la web.
No solo en ese pequeño menú desplegable, sino en otro sitio del sistema de archivos
que podrían recordar los mejores o los peores lugares donde de verdad estuviste.
Por estas y otras razones algunas veces
es necesario borrarlas o por lo menos tenerlas en cuenta.
Y francamente, desde una perspectiva de desarrollo,
una de las razones por las cuales alentamos a los estudiantes a usar
modo de incógnito de vez en cuando, para fines de desarrollo
es esencialmente que se limpien todas sus cookies.
El modo incógnito se deshace de todas sus cookies
temporalmente, y así pueden interactuar con el servidor
de una manera más predecible.
Eso solo es útil para los desarrolladores de software,
que no sean confundidos con viejas cookies vencidas.
¿Alguna pregunta acerca de las cookies?
De acuerdo, ¿a quién le importa?
Es que todo está muy bien.
Ahora podemos ser un poco más paranoicos cuando se use la web.
Pero, ¿qué podemos hacer realmente con esto ahora que es procesable?
Bueno, si continúo hacia CS50 IDE, déjenme ir directo y abrir un ejemplo
que también pueden mirar más tarde en el sitio web del curso.
Esto se basa un poco en la tienda web que improvisé.
Es súper común en estos días, tanto como adquirir cosas en la web.
Por supuesto cuando compras cosas en la web, con suerte
el sitio web recuerda lo que te interesa.
Si vas a amazon.com y haces clic en agregar al carro, ¿a dónde va eso?
Bueno, pensemos en eso.
Amazon recuerda de alguna manera, después de iniciar sesión, quién soy.
Y podemos suponer que ellos hacen eso a través de las cookies.
Entonces, colocan algo parecido a un sello en mi mano
y mi navegador recuerda a Amazon cada vez que hago clic en una página
que yo ingresé anteriormente.
¿Qué crees que hace un servidor cada vez que agregas algo a tu carrito,
o el doble de cantidad, o algo más en tu carrito?
Además, ¿en dónde se almacena esa información?
¿Díganlo de nuevo?
PÚBLICO: [INAUDIBLE]
DAVID: Así que solo basta con el encabezado para
colocar esa cookie porque en realidad, ustedes propusieron
que previamente almacenemos cosas en un servidor, ya sea en un archivo CSV,
o en una RAM, o actualmente en una base de datos.
Si pueden almacenar algo, lo quieren en el servidor,
y para recordarlo solo es suficiente hacerlo por medio de esta cookie,
que la persona que inició sesión antes se identifique de manera única,
a partir de entonces por el valor de esa cookie,
123456 o lo que sea.
Sí.
PÚBLICO: ¿Pero hay una lista asociada con su cookie?
DAVID: Hay una lista asociada con mi cookie.
Perfecto, eso es realmente lo que sigue, sí, exactamente.
Echemos un vistazo a lo que realmente significa esto.
Esta es una aplicación basada en la web.
Para aquellos que no estuvieron presentes la semana pasada,
o la semana anterior, o todo el semestre, esto
es un lenguaje de programación llamado Python.
Es el lenguaje que comenzamos a utilizar la última semana.
Este usa un entorno, es un software disponible gratuitamente
que alguien más escribió, llamado Flask diseñado para implementarlo en web
con aplicaciones basadas o sitios web.
Lo que hacemos en CS50, es recordar no implementar sitios web estáticos.
No estamos hablando de diseño web, per se,
que tiende a ser el arte de crear contenido estático, de sitios
web muy hermosos, en realidad estamos aquí por la programación web,
que usa la lógica para generar web aplicaciones o sitios web dinámicamente.
Y Python nos deja hacer esto.
Esto, es un repaso de la semana pasada, es la línea mágica
la cual dice: Dame una aplicación web basada en Flash.
Y con esto vienen ciertas funciones, como la capacidad para decir,
hey Flask, define una ruta para la diagonal.
Eso significa que cada vez que el usuario visita diagonal, la página predeterminada
en un sitio web, ¿qué archivo devuelve, solo para ser claro?
Index.html.
La semana pasada vimos dónde se encuentran estos index.html,
que son formatos y muchas cosas más.
Pero esto simplemente significa representar index.html.
Recuerden que puedo ejecutar esta aplicación web de la siguiente manera.
Si entro al directorio de la tienda y escribo flaskrun,
se activó un servidor web, por así decirlo, en la nube,
que literalmente me dice la URL para visitar.
Continuaré directo a hacer clic en esto y en Abrir.
Vemos una tienda súper simple.
Dejen me acerco.
Es realmente horrible, no he usado ningún CSS.
Esto, de hecho, no es diseño web.
Hoy en día, todo esto es funcional.
Y verán que, aunque el proyector está un poco nublado,
existen tres campos de texto ahí.
Hay un número para Foo, un número para Bar,
y un número para Bas, con los que si estoy familiarizado; estas
son solo palabras de referencia en las ciencias de la computación
cuando se necesita hablar de algo que no necesita un nombre específico.
Es como x, y y z en matemáticas.
Aquí mismo hay una tienda de Amazon.com que vende tres cosas,
Foo, Bar y Baz.
Y puedo comprar cualquier cantidad de estas cosas.
Pero lo que no tenemos aún es la capacidad
real de permitir que un usuario interactúe con un formulario web
y luego almacenar esa información y cambiar esa información.
Rasguñamos de cierta forma la superficie de un archivo CSV [INAUDIBLE]..
Pero ahora tenemos la capacidad de almacenar algo en una base de datos.
Regresaremos al IDE por un momento y nos centraremos exactamente en eso.
Antes que nada, aquí está cómo es que funciona este programa.
Continuaré y me compraré un Foo, dos Bars y tres Bazes,
cualesquiera que sean.
Continuaré y haré clic en Comprar.
Y ahora veo mi carrito de compras.
Y para ser claro, coloco el cursor sobre la URL, estoy en la diagonal
precedido por la larga URL, que es donde comencé.
Fíjense qué bello es.
Puedo recargarlo y sigue siendo el mismo.
Igualmente, puedo volver a cargarlo.
Incluso puedo cerrar una pestaña, abrir una nueva, regresar, y aún se mantiene.
Ahora veamos qué sucede realmente bajo la cubierta en términos de código.
Bueno, para C/cart es realmente muy sencillo.
Solo se procesará cart.html.
Pero con el cart.html, que yo escribí antes de esta mañana,
no sabía de antemano posiblemente que yo
compraría un Foo, dos Bars, y tres Bazes.
Así que, posiblemente no es hardcoded.
Existe otra característica de los formatos
en una aplicación web como esta, por la cual
además de decirle a la computadora que me muestre cart.html,
recuerden que puede emitir valores.
Pienso que lo hicimos una vez más.
Carrito es solo el nombre que le di como concepto de un carrito de compras.
Iré directo a emitir algo llamado una sesión.
Y una sesión es el término artístico que describe
lo que sea que sea que el servidor recuerda del nombre
de usuario por su cookie.
El navegador del usuario posee el sello de mano, la cookie,
123456.
El servidor, en realidad almacena la sesión, que
solo es una caja llena de valores, algo que
que fue puesto antes en esa caja.
Y entonces, ¿qué es lo que ahora tengo en mi cart.html?
Continuaré con los formatos, que abre cart.html.
Y esto lucirá especialmente críptico.
Para aquellos que vieron esto antes, recuerden que
esto solo significa descender de o heredar de layout.html.
Ahí es donde es parecido al estándar HTML, en cabeza, cuerpo
y todo eso.
Entonces, esto dice, hey, servidor.
Aquí viene el cuerpo de mi sitio web.
Aunque tenemos relativamente poco ahí.
Aquí tenemos mi gran título en negritas,
cart.
Hace un momento vimos exactamente eso, un gran cart en negritas.
Y por aquí, noten que uso
Jinja, ese lenguaje de plantillas: muy ligero, y similar a Python,
y obtendrás más como acostumbrabas con el tiempo.
Noten que tenemos aquí un bucle que dice para cada elemento en el carro,
continúen y hagan este dos puntos que, parece muy críptico.
Pero, ¿alguien recuerda quizás de [INAUDIBLE] la última vez,
¿qué significa esta sintaxis con las dos llaves a la izquierda y a la derecha?
PÚBLICO: Variables.
DAVID: Variables, que solo conectan estos valores aquí.
Y aparte, resulta que estas llaves en realidad se
escapan de nuestros datos, por decirlo así, de una manera tal
que si el usuario escribe un tipo de caracteres peligrosos
en su teclado, esto evita que se conviertan en un problema,
pero hablaré más sobre esto en otro momento.
Y esto solo dirá, item: cart [item].
Y esta podría ser una nueva sintaxis para algunos.
¿Dónde hemos visto antes estos corchetes?
¿Qué significa eso en C?
PÚBLICO: ¿Arreglos?
DAVID: Arreglos.
En Python, todavía tenemos arreglos, pero se llaman listas.
Pero también, tenemos otra función y ustedes no conocían esto
solo echando un vistazo a la sintaxis.
Pero cuando ves cuadrado corchetes al lado de una palabra
como cart, dentro del cual no es un número,
pero se volverá una palabra.
Esta palabra literalmente será Foo, o Bar, o Baz.
Es una manera de usar una tabla hash, un diccionario, o un dict en Python,
como le decimos, porque el carro lo emitió dentro de este formato
y dentro del carrito hay muchos de elementos como Foo, Bar y Baz,
puedes obtener el número de Foos haciendo cart, corchetes, Foo, que se vería
si lo vuelvo hardcoded, como este.
Puedes obtener el número de Bars al hacer esto.
Y podemos obtener el número de Bazes que hacen eso.
Sin embargo, solo se conecta un artículo, que es una variable,
Saldré de este bucle, con los Foos,
luego los Bars, después los Bazes, y demás artículos.
¿Cuál es el resultado final?
Volvamos al navegador.
Cuando presiono recargar, la razón por la que vimos Foo, dos puntos, 1,
Bar, dos puntos, 2, Baz, dos puntos, tres, es debido a ese formato.
Y si lo cargo nuevamente, una, y otra vez.
Veo lo mismo porque es probable que mi navegador esté haciendo algo.
Así que déjenme hacer eso.
Iremos directo a inspeccionar.
Déjenme ir a la red.
Y solo por añadir, ustedes también deberían entrar en esa costumbre.
hacer clic en conservar sesión.
Porque de esta manera, si cambian páginas, la sesión no desaparece.
Todavía pueden hurgar en lo que ven.
De nuevo, esta es mi pestaña de red.
Quiero ver lo qué Chrome hace para comunicarse con esta aplicación web.
Iré directamente a mantener Shift y luego hacer clic en recargar.
O si se hace clic y se mantiene,
probablemente nunca hayan notado esto.
Pero si hacemos clic y esperamos en el botón de Reload en Chrome,
podemos hacer un Normal Reload, que es la que todos hacemos, todo el tiempo,
un Hard reload o un Empty cache y Hard Reload, la cual solamente
es una forma de deshacernos de todas las cookies,
todos los restos de ellas, y reiniciar todo de manera contundente, lo cual es
genial para el desarrollo de software y siempre sabremos en qué estado estamos.
También podemos mantener presionado Shift,
¡ups!, y hacemos clic en Reload.
Así que hagámoslo.
Reload y aquí vamos.
Eso hizo una solicitud porque no hay imágenes, CSS, o cosas elegantes
para que se envíen más solicitudes.
Esto será un poco abrumador a primera vista.
El IED en sí mismo usa cookies para otros fines.
Así que, ven montones de cookies, las cuales
no tienen nada que hacer con esta aplicación, que lo hacen
con el entorno de programación.
Pero podemos enfocarnos es esto.
Noten que cada vez que obtengo una respuesta del servidor,
me envía a set cookie y luego algún valor.
Ahora, este es un valor más largo que 123456, pero es
lo mismo, un gran número al azar
Entonces, qué pasa cuando la vía del servidor es
comunicarle a mi navegador que son los usuarios 123456 o lo que sea,
con ese gran número largo.
Se supone que mi navegador presenta eso, una, y otra, y otra vez.
Por último, ¿qué pasa realmente cuando se continua comprando y
se compran 10 de estos, y 10 de estos, y 10 de estos y se hace clic en Comprar?
Noten que si miro el formato, se reducirá radicalmente la actualización.
Y es a través de Post,
que si regreso al código para saber qué sucede,
déjenme regresar a application.py enfocándome en la actualización.
Así es como actualizo el contenido del carrito lateral del servidor.
Se dice que para cada elemento en la forma que
se sometió el formulario de solicitudes, se continúa y se actualiza la sesión
del artículo en corchetes será Foo o, Bar, o Baz porque eso es lo que
está en el formato y se almacena allí,
request.form.get.
Así que obtiene el valor de ese artículo, si es 10, y 10, y 10 o 1,
y 2, y 3, cualesquiera que sean los números que el ser humano tecleó.
Y, ¿por qué piensan que colocamos la palabra int?
¿Por qué podría ser necesario?
Sí.
PÚBLICO: [INAUDIBLE]
DAVID: Sí, es así de sencillo.
Es una especie de casting en C. Que el usuario escribió en forma de texto.
Pueden parecer números como 1, 0.
Ciertamente luce como 10.
Pero no es un número.
Esa es una cadena que parece un número.
Se usa int para que se convierta en un número real, y se hagan cálculos sobre él.
En resumen, ¿qué es lo que hizo esto posible?
No hemos usado esto antes, pero tal vez lo vieron en Pset 6,
bien en el código de distribución en Pset7, el cual ahora está en el sitio web.
Hay algunas líneas de código que solo habilitan sesiones.
Con esas pocas líneas, somos capaces de decirle a Flask, hey Flask,
para que el programador use lo que llamamos una sesión,
de vuelta para que el programador pueda usar lo que se llama una sesión, que
¿Además qué importé aquí?
Añadí algunas funciones adicionales.
Y si alguna vez se preguntaron a dónde van todos estos datos,
seguiré adelante para detener el servidor, limpiar mi terminal y escribir LS.
Hace un momento, las únicas dos cosas en esta carpeta
fueron application.pi y formatos.
Ahora, aparentemente hay un directorio llamado sesión de Flask.
Si se preguntaban dónde Amazon almacena el contenido de tu carrito de
compras o donde Facebook almacena a María o a Brian, una vez que ingresaron,
es probable que estén en una carpeta, en un archivo como esta
donde estas grandes y largas cadenas representen su valor de cookie o,
mejor aún, están en una base de datos.
Y esta es la razón de que estén allí, porque al parecer
cree cuatro cookies al volverlo a cargar y probarlo un poco, en horas diferentes.
OK, cualquier pregunta sobre, ¿cuál es su potencial,
o el uso de cookies, y qué son las sesiones?
Está bien, continuemos con la transición a la resolución de
problemas un poco más poderosos con las llamadas bases de datos.
Esta es una representación de lo que hicimos la semana pasada,
haremos un poco más hoy y también lo harán con la serie de problemas 7.
Tuvimos navegadores y los servidores se comunican entre sí
con el uso de cierto tipo de modelo.
El modelo generalmente se llama MVC, controlador de vista de modelo,
aunque no lo llamé así la semana pasada.
Y MVC significa esto,
se escribe el código denominado controlador.
Esta es la lógica, la propiedad intelectual,
la lógica comercial de su aplicación.
Si se envía un formulario, entonces se agrega la actualización del carrito.
Cualquiera de estos tipos de if, else, y bucles
están en lo que denominamos código de controlador, alias application.pi.
También se pueden tener vistas, V en MVC, que son específicamente sus formatos,
la idea es que separan todo de lo interesante, jugoso, intelectual
parte de su programa en el código del controlador, la application.pi,
y todo lo importante pero de cosas estéticas
en su directorio de plantillas, alias vistas.
De esta manera, entre otras cosas, ustedes, por ejemplo,
todos pueden implementar la lógica de un sitio web
mientras que un amigo suyo que ciertamente sea mucho mejor que yo en diseño
puede hacer todo lo estético, las cosas, todas las vistas,
en el directorio de formatos, y ustedes pueden colaborar más efectivamente.
Pero hay una carta más en MVC.
Es el controlador de vista modelo.
En lo que enfocaremos ahora es sobre la M en MVC.
Este modelo es solo una manera general de hablar sobre los datos,
como a dónde van los datos reales.
Deben tener el modelo mental para avanzando mientras se escribe el código,
a pesar de que las líneas no serán claras siempre como
la claridad de esta imagen sugiere, en cualquier momento se escribe
el código en application.pi ese puede ser el código del controlador.
Como, el flujo intelectual de trabajo de su aplicación.
Cada vez que se ejecuta HTML, o CSS, o Jinja,
que es la vista de su aplicación, la estética, la presentación de
la información.
Y cada vez que se leen y se escriben datos a largo o corto plazo.
Ese es el modelo.
Algunas veces las líneas serán muy borrosas
y todo podría estar en el mismo archivo.
Pero esas tres tipos de operaciones son el modelo mental para adoptar.
Así que vayamos allí.
Recordarán que en la semana cero, presentamos a este tipo, Scratch,
y el lenguaje de programación gráfica con el que se comenzó el semestre.
Una semana más tarde, presentamos C, que tenía las mismas ideas y capacidades
en su mayor parte, pero solo se usó teclado en lugar de gráficos y una GUI.
Y hace una semana se hizo la transición a Python, hace un par de semanas
ahora a Python, que es que su espíritu es muy similar.
Pero como recordarán con gran deleite, o frustración,
puedes obtener mucho más trabajo hecho rápidamente,
por ejemplo, en PSet5,
usando el lenguaje correcto.
Y aquí también se comenzará a usar una nueva herramienta
para el trabajo llamada SQL, o Lenguaje de consulta estructurada,
o S-Q-L. Este es otro lenguaje, pero es mucho más pequeño que Python y C
como veremos hoy.
Pero es un lenguaje que normalmente se usa para
comunicarse con una base de datos.
Entonces con base en su familiaridad, ¿qué es
una base de datos, incluso si en realidad nunca las usaron o programaron
una antes?
PÚBLICO: [INAUDIBLE]
DAVID: Es el lugar donde están sus datos de la tienda.
Una base de datos es un lugar donde se almacenan datos, una base donde se guardan
quizás,
eso sea verdad.
¿Y qué significa eso realmente?
Una base de datos, puede ser un servidor web, que es una pieza de software.
Podríamos pensar en esto como una entidad física, pero
una base de datos técnicamente es un programa de base de datos y
es como escuchar conexiones en un servidor web o uno de correo electrónico.
Y cada vez que recibe solicitudes, les da una respuesta.
Tenemos, el mismo servidor del cliente en relación a lo que hacemos con la web
en sí misma.
Las bases de datos son más inteligentes, más rápidas en el almacenamiento
que sin duda, alguien un poco más viejo que yo.
Y espero que sean mejores que los archivos CSV.
Recuerden, usamos CSV para almacenar a los inscritos [INAUDIBLE] la semana pasada.
Creo que fuimos Rob, María y yo a la vez.
¿Qué hay de bueno en eso?
¿Qué problema resolvimos al presentar el ejemplo de los archivos CSV?
Sí.
PÚBLICO: [INAUDIBLE]
DAVID: No tenían que ir a mi bandeja de entrada, ¿cierto?
Una de las otras versiones del programa de registro
fue enviar un correo electrónico al supervisor en turno [INAUDIBLE], que
está bien porque él o ella puede usar etiquetas y hacer un seguimiento allí.
Pero eso no es una base de datos.
Solo están abusando de Gmail como una base de datos.
¿Por qué no ponen un archivo de texto en su lugar como un CSV?
Porque, ¿qué tipo de programas pueden abrir CSV?
Sí, como Excel, Números y programas de hojas de cálculo similares.
También se pueden importar a las hojas de cálculo de Google.
Eso fue una ventaja de usar CSV.
Pero ¿tal vez sea una desventaja aún si en realidad no
experimentamos tantos inconvenientes?
PÚBLICO: [INAUDIBLE]
DAVID: ¿Más difícil para qué?
PÚBLICO: [INAUDIBLE]
DAVID: Es más difícil hacer cosas con eso, porque al final del día,
es solo un estúpido archivo de texto, y nosotros los humanos
hemos acordado colocar comas entre los valores que nos importan.
Pero eso es todo.
Este no tiene funciones.
Se abre ese archivo, para ver texto ASCII, con comas con él.
No se obtienen, características, sin funcionalidad.
¿Tienen algún otro pensamiento?
PÚBLICO: [INAUDIBLE]
DAVID: ¿Por qué es ineficiente?
PÚBLICO: [INAUDIBLE]
DAVID: Es más difícil encontrar cosas.
Ciertamente, no en el caso de, María, Rob y mío.
Pero tan pronto como comiencen a tener cientos de estudiantes registrados o miles
de clientes en su base de datos o cientos de miles, como en CSV,
lo mejor que ellos pueden hacer es usar el tiempo lineal para todo.
Tienen que buscar en todo el archivo de arriba a abajo.
¿No sería mejor si se toman ideas de la semana cero,
integrarlos en el contexto de este problema, bases de datos,
se consultan datos, se pide cambiarlo, eliminarlo y editarlo
mucho más fácil que nos permiten los pequeños archivos de texto?
Entonces, ¿en qué deberían pensar cuando piensen en una base de datos?
Bueno, hay diferentes tipos.
Hoy nos enfocaremos en las denominadas bases de datos relacionales, que
es una forma elegante de decir tablas de columnas y filas.
Esta es una captura de pantalla de las hojas de cálculo de Google
con la que probablemente estén familiarizados.
El proyector parece esconder, que en realidad hay
filas y columnas aquí.
Y en cambio, solo vemos una gran caja blanca.
Pero, existen filas y columnas dentro de este
como se puede ver en la pantalla.
Y si uso [INAUDIBLE] esta es una captura de pantalla.
Así que, ni siquiera puedo habilitar filas y columnas.
Porque tenemos nuestras columnas y filas.
¿Por qué es útil esto?
Bueno, si alguna vez almacenaron datos de un grupo de estudiantes, o
para sus clientes, o para otras aplicaciones en la casa,
probablemente tienen el hábito de almacenar cosas en filas y columnas.
¿Qué representa regularmente una columna en una hoja de cálculo?
¿Qué tipo de cosas podría representar?
Y aquí hay una versión real de las hojas de cálculo de Google.
Permítanme resaltar esto y encenderlo porque hay líneas más oscuras.
Estas son nuestras filas y columnas.
Cuando estás usando una hoja de cálculo, tal vez por experiencia personal,
¿Qué ponen en las columnas?
¿Disculpen?
PÚBLICO: [INAUDIBLE]
DAVID: ¿categorías de qué?
Denme un ejemplo concreto.
PÚBLICO: [INAUDIBLE] el nombre del estudiante y laboratorio en el que están,
DAVID: Oh, ¡qué maravilloso ejemplo!
Si podemos decir, el nombre del estudiante, su dormitorio, tal vez
su correo electrónico, o si se colectó, su número de teléfono
y muchas otras cosas.
Y saben, solo para ser ordenados podríamos ponerlos en negritas,
y pueden usar funciones como esta, que simplemente bloquea esa fila.
Pero estas son solo características de GUI.
Estas no son del tipo intelectual que resulta interesante.
¿Qué se coloca generalmente en cada fila?
La primera fila es especial y por lo general,
es porque se puede bloquear.
¿Qué se pone en las filas?
PÚBLICO: [INAUDIBLE]
DAVID: ¿Disculpen?
PÚBLICO: Elementos [INAUDIBLE]
DAVID: Sí, los datos reales,
los nombres de los estudiantes.
Si como David, se registró en Matthews,
podríamos colocar su información ahí.
Y después si Rob se registró como Thayer ponemos su in..
oh, ese no es,
Rob de Thayer, no Rob de Bowden.
Después, María, quién,
maldita sea, le pregunté esto el otro día.
¿Dónde vive?
[INAUDIBLE] Matthews, igual que yo, por qué debería recordarlo.
OK, así que, ahora podríamos tener varias filas en esta base de datos,
cada una representa una entidad y sería la forma elegante para describir dónde
una entidad es una cosa del mundo real, un objeto físico o lo que sea que les
importe.
Así es como podemos formarnos en esto.
Por supuesto, literalmente, se pueden formatear cosas usando Excel o Números
o la hoja de cálculo de Google, como la columna de formato, del tipo que
presenta los datos de una manera diferente.
Tal vez, se centra a la izquierda, o las líneas a la izquierda o a la derecha.
Tal vez elimina los ceros a la izquierda.
Tal vez agrega signos de dólar, porcentajes.
Se puede presentar la información de diferentes maneras.
Pero en su mayor parte, en este momento, es solo texto que he escrito.
Si realmente se quiere encontrar a alguien en esta hoja de cálculo, ¿qué puedo hacer?
Bueno, se puede escribir Command-F y después se escribe Rob.
Y ahí vamos.
Encontramos a Rob.
Pero, ¿qué hizo la hoja de cálculo?
Buscó los parecidos de arriba a abajo con R-O-B,
pronto lo encontró, y se destacó esa fila.
Y si tuviera miles de filas o decenas de miles
de filas en la hoja de cálculo, Rob podría recorrer todo el documento
hasta la parte inferior, la cual se señala que podría tomar más tiempo
encontrar realmente todas las instancias de Rob.
Y, de hecho, los programas como Excel y Números
e incluso las hojas de cálculo de Google después de un tiempo se descomponen.
De hecho, yo experimenté esto en la escuela de postgrado
yo mismo hice una investigación donde quería personas para analizar datos
y era conveniente hacer doble clic en mis archivos CSV,
abrirlos en Excel, y visualizar o buscar algunas de las filas
de interés para mí.
Pero debido a que ejecutaba simulaciones muy grandes,
Tenía más de 65,000 filas de datos y Excel simplemente no podría hacerlo.
Al hacer doble clic, diría, lo siento, este archivo
es demasiado grande porque alguien de Microsoft, en versiones previas de Excel,
decidió, como primera cosa y la más importante, que seguramente nadie
necesitaría más de 65,000 filas en este producto.
En resumen, para representar el número de fila usaron cierto número de bits.
Si lo recuerdan, solemos utilizar potencias de 2 o múltiplos de 8,
por ejemplo, 8, 16, 32 y así sucesivamente.
Bueno, 16 bits, del 2 hasta el 16, son 65,536.
En realidad, tendría 65,537 filas o más.
Algo como Excel no me sería útil,
y tendría que usar una base de datos reciente como Microsoft Access,
Oracle, o algo como lo que veremos hoy, SQLite.
Entonces, tan pronto como alcancen el límite del programa
por lo cual, se vuelve lento para analizar o no puede abrir todos los datos,
tampoco pueden editar la información o eliminarla, de una mejor manera
que la lineal, quizás sea tiempo para una base de datos más reciente.
Y una de estas bases de datos se llama SQLite.
Entonces, vamos a ver el SQL, o lenguaje de consulta estructurada.
El SQLite es una muy ligera y generosa
implementación de esta base de datos.
Se dice que es ligera porque
no necesitamos licencias de software especiales.
Y tampoco necesitamos instalarlo.
Todo lo que tenemos que hacer es almacenar los datos en un formato binario.
Hasta ahora en CS50, prácticamente hemos
guardado casi todo en ASCII o en formato de texto excepto series para 4 imágenes P.
Bueno, hoy volveremos a almacenar cosas en el formato binario, de ceros y unos.
Aunque ya pasamos el punto en el que nos preocupamos por cómo se ven
los ceros y unos, y por sus patrones.
El SQLite va a gestionar toda esa complejidad para nosotros,
y la va a almacenar en un enorme archivo binario que contiene
ceros y unos del mismo tipo de información al igual que David, Rob
María y otros, pero de manera mucho más eficiente
porque una de las cosas que obtenemos de una base de datos
es el resultado del esfuerzo de mucha gente inteligente, tratando
de descubrir ¿cómo podemos, en pro del mundo, almacenar datos más eficientemente?
¿Cómo proveemos a usuarios en todo el mundo, funciones de búsqueda, eliminación
y edición más eficientes, de lo que podrían
implementar por ellos mismos?
Y en el corazón de CS50, de alguna manera
"nos subimos sobre los hombros" de las personas que nos han precedido.
Ahora, ¿qué significa esto en términos reales?
Vamos a utilizar, al menos, una de dos herramientas.
Existe una herramienta que se llama PHP minuto resaltado, pero que por casualidad
fue escrito en otro lenguaje llamado PHP.
Pero sucedió por accidente.
Vamos a usarla como una herramienta gráfica, la cual
nos permite interactuar con el programa de la base de datos.
Pero también existe una versión para la ventana de la interfaz, de una herramienta
de gestión llamada SQLite o de manera técnica SQLite 3,
que además es una forma para interactuar con la base de datos, basada en texto.
Pero, así es como vamos a visualizar la base de datos
en la ventana de mi interfaz o en mi navegador.
Al final del día, vamos a hablar con nuestra base de datos, mediante
un verdadero código en Python.
Pero antes de que lleguemos allí, sembremos en nosotros mismos
algunos de los compontes básicos que tendremos
a nuestra disposición con este lenguaje.
A diferencia de C y Python, donde por lo general nos enfocamos
en las operaciones lógicas, condiciones, bucles, funciones y cosas por el estilo,
algunos de estos existen en SQL.
Pero en realidad, solo nos enfocaremos en las operaciones,
es decir, en los verbos que SQL soporta.
Es un modelo mental algo diferente, a los que tenemos en C y en Python.
Es un hecho, que las operaciones más frecuentes
que usaremos al guardar datos, no las haremos en una hoja de cálculo como Google
sino, más bien, en un archivo binario de tipo SQLite para estas cinco operaciones.
Podemos crear tablas.
Podemos crear e insertar filas.
Podemos seleccionar filas de la tabla.
Podemos actualizar y también eliminar filas de la tabla.
Es algo similar a lo que esperaríamos
obtener de un programa para bases de datos.
Lo que sucede es que también son más especializados.
Se parecen a los verbos que utilizamos.
Y aunque, lo más común es que los capitalicemos,
no es necesario hacerlo.
Ahora veamos algunos ejemplos.
Si quisiera, en un programa de base de datos actual,
crear algo equivalente para esta idea,
es decir, filas, columnas y objetos llamados tablas,
así es como podría hacerlo.
En mi programa para administración, el cual veremos después, o en un código,
Puedo crear líneas como esta, una a la vez.
Vamos a examinarlo.
Lo que ahora aparece en amarillo es CREATE TABLE.
Si queremos crear algo equiparable ya sea en binario, o para la computadora
de una hoja de cálculo de Google para [INAUDIBLE] inscritos,
lo que literalmente haríamos en CREATE TABLE, es poner registrants entre comillas
donde ese será el nombre de la tabla u hoja que ocuparemos.
Pero todo esto no cabía en una sola línea.
Así que lo resumí.
Pero en realidad, es un comando largo.
Luego entre paréntesis, definiremos una lista separada para todas las columnas
que deseamos tener en esa tabla, pero
pero esto es más laborioso que Excel, Números y
las hojas de cálculo de Google, ya que también debemos definir otros detalles.
Por ejemplo, si la columna que está más hacia mi izquierda o primera se llamará ID
la segunda va a llamarse Name y la tercera
se llamará Dorm
sería muy parecido a lo que propusieron antes, pero
no nos importará el correo electrónico, el número de teléfono y cosas por el estilo.
También he añadido, para una buena medida, un identificador único, un entero
para identificar a cada novato inscrito en deportes.
Hay algunos otros detalles que estoy proporcionando claramente.
Como, ¿qué tipo de información sería obviamente un nombre?
PÚBLICO: [INAUDIBLE]
DAVID: Texto, pero de hecho, SQLite usa un tipo de datos
que no se llama cadena, sino literalmente texto.
Al igual, que dorm será texto.
Pero ID va a ser un poco diferente.
Podría ser texto.
Pero se vuelve más eficiente si solo usamos números
para identificar de un modo único a los humanos, ¿cierto?
Porque incluso en mi nombre, D-A-V-I-D, ¿cuántos bytes necesito como mínimo?
¿Cuántos bytes?
D-A-V-I-D. Cinco, sí, cinco bytes en total para D-A-V-I-D.
Pero si en cambio, me representan en una computadora mediante un número como el
uno, el dos o incluso el número 2 mil millones si tenemos muchos usuarios,
¿cuántos bytes se necesitan para almacenar ese número?
PÚBLICO: [INAUDIBLE]
DAVID: Bueno, aún son pocos.
Si solo rep, si mi número ID de Harvard es solo un único número,
como uno, dos o 2 mil millones, ¿cuántos bits
necesitamos para representar un entero como ese?
Por lo general, hemos usado cuatro.
Si queremos un entero más grande, podríamos usar ocho,
pero por lo general, va a ser mucho menor que el número de caracteres
que en realidad estamos transmitiendo.
Esa es la razón por la que debo usar un integer.
Regresaremos a lo que significa primary key en un momento.
Pero, en resumen, esa línea, esas líneas en amarillo
si se ejecutan en un programa de base de datos, van
a crear el equivalente a una hoja de cálculo que contiene
las tres columnas que me interesan.
Posteriormente, si deseo añadir a alguien como yo en esa tabla.
Así es como utilizamos el lenguaje SQL para hacerlo.
Literalmente ejecutamos "Insert into registrants",
el cuál es el nombre de la tabla, luego hacemos una lista separada
entre paréntesis de las columnas, para la cual tenemos los valores
que estamos a punto de proporcionar.
Y esto nos permite cambiar el orden, si así lo queremos,
pero por ahora lo mantengo vacío y voy de izquierda a derecha.
Luego, literalmente escribimos "values".
Y de nuevo entre paréntesis, hacemos una lista delimitada por comas, con los valores
que deseamos introducir dentro de esas columnas.
Pero, debemos verificar que si ID está en la primera posición,
pondremos el número primero.
Si Name es el segundo, pondremos un nombre en el segundo lugar y así sucesivamente.
Así es como lo controlaremos.
Por otra parte, si queremos buscar a todos los que se registraron para
[INAUDIBLE],, veremos la sintaxis de esta manera.
Le indicaremos a la base de datos que seleccione a todos sus elementos,
más específicamente, desde la tabla llamada registrants.
Y eso, literalmente nos devolverá
cada fila, en cierto modo, como un código de la tabla. Si además,
quiero cambiar mi nombre porque no seguí las instrucciones
y necesitamos escribir mi nombre completo para los deportes, bueno,
desde "UPDATE registrants" puedo actualizar a los inscritos en la tabla,
y escribimos SET "name" = David Maland en la columna para nombres,
pero esta última parte es sumamente importante.
Si en "Where id" no ponemos que esto equivale a 1, intuitivamente ¿qué creen
que podría suceder en la base de datos?
PÚBLICO: [INAUDIBLE]
DAVID: Todos los nombres serían David Maland, lo cual estaría incorrecto.
Y algunos de los directivos, que fueron nuestros compañeros del curso en C
recordarán que hace años tuvimos
un compañero de clase llamado Michael Tingly
cuyo apodo era "Cosquillas".
Pero, por error, ejecutamos una búsqueda en SQL en la que omitimos
esta condición, este predicado.
Cuando debíamos indicarle que "where id" era el número ID de Michael Tingly
pero en vez de eso lo quitamos.
Y desde ese momento, tuvimos como 700 Michael "Cosquillas" inscritos en el curso
hasta que lo restablecimos desde la copia de seguridad.
Esto también les podría pasar a ustedes.
Por último, si queremos eliminar a alguien,
seguiremos los mismos principios, pero con diferentes verbos "DELETE FROM"
de la tabla en la cual queremos eliminar algo con "WHERE",
e indicamos el número de ID, en este caso.
Y solo por si acaso, aunque no es estrictamente
necesario, permítanme ser consistente y también capitalizar esto.
El motivo de la capitalización, solo para dejar esto claro,
es que sirve de ayuda al ojo humano para distinguir
la sintaxis del SQL, de las palabras que los humanos hemos inventado
para nuestras hojas de cálculo.
También notemos algunas otras características.
Puse de manera uniforme, en minúsculas, todos los nombres de mis columnas
id, name y dorm, lo cual es muy común, pero esto no es estrictamente necesario.
Toda la tabla también está en minúsculas.
Pero en ninguno de los nombres de la tabla hay espacios.
Y tampoco estoy usando caracteres de moda, como signos de admiración,
como "registrants!", o algo por el estilo.
Lo mantengo limpio con caracteres muy simples
y eso es bueno para la portabilidad.
Este es lo más habitual.
Es posible que ya hayan visto o experimentado esto en el IDE.
Cada vez que usamos espacios o caracteres de moda,
las computadoras suelen confundirse porque no los esperan.
Entonces, la mejor práctica con cosas como el diseño de bases de datos
es evitar por completo esos problemas y mantener las cosas simples.
Podemos usar guiones bajos en lugar de espacios, si realmente queremos poner
una separación entre dos cosas.
Ahora, existen diferentes tipos de datos.
Pero tampoco son tantos y los únicos
que nos preocuparán en los próximos días son estos de aquí, uno de los cuales
tiene un nombre extraño.
Pero SQLite, la base de datos que estaremos utilizando, admite texto,
enteros o variables, alias int, como ya hemos visto, algunas de estas cosas
tienen nombres falsos o apodos
Null, significa lo opuesto a tener algún valor.
En realidad podemos indicarle, no, no hay ningún valor aquí.
¿Qué es lo que significará Real, tal vez?
PÚBLICO: [INAUDIBLE]
DAVID: Sí, algo como un número real o un valor de punto flotante,
igual a como lo llamamos en C y en Python.
Y luego BLOB es un objeto binario grande.
Así, si queremos almacenar los ceros y unos en nuestra base de datos,
lo almacenaremos como un BLOB, lo cual no es tan común
porque hay mejores formas de almacenar datos binarios, por ejemplo, en archivos.
Pero esto también es posible.
Es importante resaltar que, existen otros tipos, con otros formatos
pero no están aquí de manera formal.
SQLite es bueno porque es bastante flexible.
Existen muchos programas de bases de datos por ahí.
Probablemente hayan escuchado de algunos, como los que mencioné,
Microsoft Access, Oracle, MySQL, Postgres SQL y otros.
Pero SQLite es una alternativa bastante flexible.
De modo que, si intentamos cargar datos desde alguna otra base, como Oracle
en SQLite, éste va a tolerar formatos no oficiales
como "date times", o lo que sería similar, "years and time" o "dates and times"
literalmente, "numeric", el cual utilizamos cuando no estamos seguros
si corresponden a un número con punto flotante o a un entero,
la base de datos puede averiguarlo para nosotros y también para otras personas.
Así que, no se sientan confundidos cuando lean sobre SQLite.
Si ven algunas cosas que no son consistentes del todo,
es porque solo son consistentes con ese tipo de flexibilidad.
Y aquí tenemos una tabla detallada de todas estas cosas de la izquierda
en ese mapa a la derecha.
A la derecha están los formatos oficiales de datos de SQLite, los cinco de aquí.
Que posiblemente veamos en los tutoriales de internet sobre SQL
montones de otros formatos.
El más popular podría ser BIGINT, que es un entero de 64 bits,
lo cual es realmente grande, VARCHAR, que es una cantidad variable de tablas
pueden ser pocas o muchas, dependiendo de los datos,
y muchas otras cosas también.
Así que, sean conscientes de los que están afuera, pero los cinco a la derecha
son los únicos que de verdad nos interesan.
SQL también tiene algunas funciones incorporadas.
También podemos hacer esto en un código de Python, como veremos.
Pero "date and time" y "datetime" nos permiten obtener la hora en curso.
De modo que, si un usuario se registra en nuestro sitio web y
queremos hacer un registro del momento en que lo hizo,
podemos declarar funciones como esta y la base de datos
lo resolverá por nosotros.
No tenemos que verificar el reloj de la computadora.
Pero lo más importante serán algunas de estas opciones.
Pero antes de seguir con más, permítanme hacer una pausa para algunas preguntas.
Sí.
PÚBLICO: [INAUDIBLE] cuando [INAUDIBLE]
DAVID: Ah, buena pregunta.
Por lo general, no.
Pero si queremos ser bastante precisos, sí.
Así que, fui bastante preciso y en realidad leí la documentación esta mañana
para asegurarme de que todas las sentencias eran correctas.
La regla de oro si somos observadores,
aunque para la mayor parte, esto no importa y no debería obsesionarnos tanto,
es que cada vez que nos remitamos al nombre de un identificador,
como se lo llama, el nombre de una columna o de una tabla,
en SQLite usaremos comillas dobles.
Y cada vez que nos remitamos a una cadena literal
que el humano ha escrito en algún lugar, por ejemplo, David Maland
y en Matthews, usaremos comillas simples.
Si se trata de algo como una entrada de usuario, comillas simples.
Si es un nombre en nuestra base de datos, entonces serán comillas dobles,
pero normalmente esto no importa.
Así que no se preocupen demasiado.
Solo por un momento, analicemos donde
comenzó esta conversación en particular.
Tratábamos de crear una base de datos u hoja de cálculo para [INAUDIBLE],
pero por alguna razón nos detuvimos antes de la parte jugosa.
Escribí algunos "names" y algunos "dorms".
Pero podría haber comenzado escribiendo un correo electrónico, el cual
tendría, con un poco de suerte, algún formato estándar, algo de algo punto
cualquier cosa.
El número de teléfono también es interesante, ¿cierto?
Al igual que, ¿cómo puedo almacenar un número?
Si lo que quiero, es que las personas solo llamen al número principal de Harvard,
sería algo como, 459 ¿Qué es esto 5,000?
Bueno, ¿debería guardarlo así?
¿10 números y dos guiones?
En vez de eso ¿debería guardarlo sin los guiones para ahorrar espacio?
¿Debería ser consistente con las convenciones internacionales y
también guardar el código del país, que ahora Google confunde con las matemáticas?
Así es el número de teléfono de Harvard cuando ponemos los números juntos
según parece.
¿Cómo almacenamos la información?
O mejor aún, ¿qué deberíamos esperar que escribieran los usuarios?
Cuando visitamos un sitio web y nos piden el número de teléfono
para comprar algo o crear una cuenta, ¿en cuál formato
por lo general, nos piden el número, al menos en los Estados Unidos?
PÚBLICO: código de área, [INAUDIBLE]
DAVID: Sí, a menudo nos lo piden [INAUDIBLE] un ejemplo como este.
Entonces tenemos que escribirlo y presionar Enter.
Y luego está almacenado, de esa manera.
Probablemente ¿también han visto los otros formatos?
Entonces, ¿cuál es la manera en la que deberíamos hacerlo?
PÚBLICO: [INAUDIBLE]
DAVID: Sí, sí, todas estas formas son totalmente aceptables,
y cualquier sitio web que nos obligue a usar un solo formato es estúpido.
Está mal diseñado.
Y esta es una de mis mayores, bueno, no es mi manía más grande.
Pero una de mis manías es cuando un sitio web de manera completamente innecesaria
tecnológicamente, pone la responsabilidad de formatear los datos en las personas.
Sin duda, sería capaz de escribir mi información de esta manera
o con el más uno, o sin los paréntesis,
o con un guion adicional, o cosas por el estilo, porque ¿solo tú sabes, lo que tú
el programador que hizo el sitio web puede hacer?
Podemos utilizar algún tipo de coincidencia en el patrón
incluso en esencia en P set 6, tira toda la puntuación,
y después almacenar solo los dígitos que queramos, o entrar
y añadirle los guiones a la fuerza, donde los queramos
o los paréntesis donde los queramos.
No es necesario que la responsabilidad recaiga en las personas.
Hay argumentos en verdad convincentes en el UX o experiencia del usuario,
los cuales me superan y se disparan en una especie de queja.
Como cuando no puedes copiar y pegar algo dentro de un campo,
esa es una mala experiencia de usuario.
Y si alguna vez han intentado copiar un campo dentro de otro
pero el sitio web ha deshabilitado esa opción, no será la mejor experiencia.
Lo peor son aquellos que no nos permiten pegar contraseñas en los formularios
porque si almacenamos las contraseñas, como es recomendable, en un administrador
de contraseñas, que las encripte, lo mejor es tener una contraseña bastante larga
y después pegarla en el formulario, en vez de memorizar una contraseña muy corta
que alguien más podría adivinar.
En resumen, a medida que nos adentremos en la programación web,
no es necesario que sea un modelo, como lo que vemos allá, pero sí considerarlo
para nuestros usuarios, por ejemplo, ¿cuál sería la mejor manera de hacer esto?
y sabiendo programación, ¿cómo puedo incorporar diferentes estilos
y también expectativas?
Pero al final del día, tenemos un problema aquí
porque, ¿qué es este número de teléfono, un número, una cadena o texto?
PÚBLICO: [INAUDIBLE]
DAVID: Si OK, escuché que unas cuantas cadenas o texto.
Lo cual es bueno porque SQLite permite texto.
Podría indicar, que cuando convierta una hoja de cálculo en comandos para SQL
o un SQL en una base de datos, podría usar texto.
Eso probablemente sea algo bueno.
¿Y qué me dicen de los códigos postales, cierto?
Si tenemos códigos postales de cinco dígitos como en los Estados Unidos,
como 02138.
¿Es eso un número o es texto?
PÚBLICO: Texto.
DAVID: ¿Texto?
¿Por qué?
PÚBLICO: [INAUDIBLE]
DAVID: ¿Perdón?
¿Dilo de nuevo?
PÚBLICO: [INAUDIBLE]
DAVID: Sí, es más como una categoría
que una cantidad, sin duda.
Ya que no tengo cero, uno, dos, tres, ocho de las cosas.
Eso quiere decir que únicamente son símbolos.
Y, gracias a un efecto secundario de la hoja de cálculo tratando de ser útil, aquí
hay un error, o una razón para almacenar esto como texto.
Escribí 02138, que es Cambridge, Massachusetts,
uno código postal bastante grande.
Y desafortunadamente, Google decidió, que no necesitamos
ese cero inicial, ¿o sí?, entonces se deshace de él.
Eso ocurre porque, al menos en las hojas de cálculo de Google, mis datos aquí,
si vamos a Formato, se almacenan automáticamente.
Google, para bien o para mal, a menudo para mal,
deduce que, si algo se parece a un número, entonces es un número, por lo tanto va a
eliminar los ceros a la izquierda, que los humanos no necesitan.
Pero si lo cambio a texto sin formato y escribo 02138, funciona como un pegamento.
Y otra historia real es, que hace algunos años,
Solía ​​usar Microsoft Outlook para mi correo electrónico.
Y luego finalmente, lo cambié a Gmail.
Pero antes de que lo hiciera, quería copiar mis contactos,
es decir, mi libreta de direcciones de Outlook a Gmail.
Entonces, Outlook tiene una función en la cual
literalmente, podemos exportar un gran CSV desde Outlook.
Y contiene columnas de, por ejemplo, todos los nombres y números de tus amigos,
direcciones y códigos postales.
Pero, estúpidamente no me di cuenta de que probablemente
no debería abrir primero el archivo en Excel para verlo,
seguramente por instinto, oprimí el Comando S o Control S para guardarlo,
porque es como un hábito.
Pero tan pronto como lo hice, Excel presuntuosamente
hizo lo mismo que Google, y eliminó todos los ceros iniciales.
Y hasta el día de hoy, como 10 años después, aún
sigo encontrando amigos cuyas direcciones son Cambridge, Massachusetts,
es decir 2138, por esa misma razón.
Entonces, el formato de los datos sí importa.
Y tendremos que tomar una serie de decisiones para establecerlo, y si además,
queremos que esta base de datos sea de alto rendimiento, es decir, rápida
también contamos con algunas otras opciones para diseñarla.
Ahora vamos a nuestro receso de cinco minutos, y cuando regresemos,
discutiremos acerca de cómo almacenar los datos más eficientemente, de modo
que nuestras aplicaciones web sean súper rápidas.
Estamos de vuelta.
Veamos qué problemas surgen ahora además de los más recientes, como lo
fue el número de teléfono.
Imaginemos que estos no necesariamente son registros de los estudiantes
para [INAUDIBLE], y de este modo, no solamente
tenemos dorms y esas cosas, pero y si en realidad se trata
de clientes en una base de datos, clientes de Amazon o algo así.
Y entonces diríamos, que las personas van a tener nombres.
Y tendrán direcciones, una dirección.
Tendrán número de teléfono, correo electrónico y seguramente
también otras identificaciones.
Así que, cuando se trata de almacenar todos esos datos aquí,
y solo para que quede claro, estos serán ahora los encabezados de mis columnas,
esta será primera columna especial,
entonces, ¿cómo escribiremos mi nombre aquí, David Malan?
¿Debería ser David?
¿En realidad, que es lo que piensan de algo tan trivial como esto,
y cuales serían algunas de las ventajas y desventajas?
Entonces, ¿cuál debería ser?
PÚBLICO: David Malan.
DAVID: David Malan, OK.
Entonces lo que guardamos es David Malan.
¿OK?
Pero un poco después me di cuenta, de que en verdad me gustaría
enviarle correos electrónicos personalizados a mis clientes,
pero se siente un poco ridículo e informal si digo: querido David Malan, cuando
evidentemente, no se siente tan cercano.
Me gustaría que dijera, querido David coma.
¿cómo resolvemos eso?
PÚBLICO: [INAUDIBLE]
DAVID: OK, tal vez deberíamos guardar los nombres y los apellidos por separado.
Y para hacerlo, quizás solo necesito repetir esto, y
llamar esto Primero, y luego ponerle a esto Último.
Así que ahora, puedo mantener separadas mis dos columnas.
¿Alguna otra idea?
Eso suena bastante bien.
O,
PÚBLICO: [INAUDIBLE]
DAVID: ¿Perdón?
PÚBLICO: [INAUDIBLE]
DAVID: Oh, también necesitamos algo para el saludo,
lo cual también conseguiríamos con algo desplegable o un cuadro de texto.
Quizás también necesitemos eso.
Así que técnicamente, lo mejor sería mover esto de esta manera.
Y esto sería para el saludo, y tal vez este
podría ser Sr. o algunos otros símbolos.
Podríamos tener que lidiar con eso, también.
¿Qué hay de la dirección?
Pasemos a eso, porque honestamente, para la mayoría de estas preguntas,
no necesariamente existe una mejor respuesta.
Puede que algunos métodos sean mejores que otros, pero incluso así tendremos
situaciones difíciles.
Por ejemplo, ahora, cada vez que quiera el nombre y el apellido del usuario,
Voy a tener que concatenarlos juntos, lo cual está bien.
En Python esto no es un gran problema.
Fue un problema mucho más grande en C. Entonces, existen ciertas compensaciones.
Como, solo tengo que hacerlo ahora, o escribir más del código después.
¿Y qué pasa con la dirección?
Podría ser: 33 Oxford Street, el edificio de CS en Cambridge, Massachusetts,
02138 EE. UU.
Permítanme hacer aún más grande el espacio para todo esto.
¿Está bien?
¿Malo?
¿Por qué?
Vayamos aquí.
PÚBLICO: [INAUDIBLE]
DAVID: ¿Perdón?
PÚBLICO: [INAUDIBLE] separar los datos [INAUDIBLE] código postal [INAUDIBLE]..
DAVID: Bien, dices que necesitamos separar los datos por calle, ciudad
país, código postal y estado, pero ¿por qué?
PÚBLICO: [INAUDIBLE] ahora para ordenar a las personas por [INAUDIBLE]..
DAVID: Sí, ese es un muy buen ejemplo.
Si todo ha sido una especie de cadena larga, la cual
los humanos y el director general de correos de los Estados Unidos entendemos,
y las computadoras analizan, no es tan fácil solamente extraer lo que nos importa
de toda esa larga cadena.
Será necesario utilizar algún tipo de heurística,
tendremos que buscar entre todos los números para obtener los códigos postales.
Y podría, como dices, no ordenar a todos los que están en Massachusetts,
o a todos los que están en el 02138, pues es como si no dividiéramos los campos.
Inclusive mecánicamente en las hojas de cálculo de Google,
no puedo ordenarlo de ninguna otra manera, aparte de 33 Oxford Street.
Pero quizás no deba preocuparme en ordenar a las personas
por sus direcciones, las cuales en realidad no tengo idea de cómo ordenar
y eso es interesante.
Probablemente necesitemos dividir esto.
Quizás esto en realidad es Street y esto ahora sea
ahora déjenme reducir esto para hacer un poco más de espacio,
tal vez esto es City, esto es State, esto es Zip,
y quizás esto ahora sea Country.
Después aquí tenemos Correo electrónico, Teléfono y así sucesivamente.
Ahora podría escribir 33 Oxford Street.
Luego Cambridge, Massachusetts, 02138, EE. UU., malan@harvard.edu, 6174495.
Miren, por esta razón no permitimos las entradas de usuario en otros formatos.
495, 5000 y así sucesivamente.
OK, supongamos que lo hacemos así.
Pero como sabrán, también Rob tiene una oficina en el edificio de CS.
Y en realidad es el Sr. Rob Bowden.
Así que ahora ambos estamos ahí.
Ups, no solucionamos esto, entonces técnicamente regresaremos aquí.
02138.
Ahora esto es: rob@cs.harvard.edu.
Tal vez compartimos el mismo número de oficina.
Seguramente también hay docenas de otras personas en el edificio de CS,
si no es que un par de cientos.
Y en realidad, esto nos produce otro problema.
Al menos si sigo escribiendo, voy a rechazar esto por alguna otra razón.
¿Qué otra cosa está mal en esto?
Sí.
PÚBLICO: [INAUDIBLE] la oficina.
DAVID: La oficina, sí.
Entonces no especificamos la oficina en el edificio.
Y nos faltan datos en conjunto.
¿Qué otra cosa aparece todo el tiempo en su cabeza?
Sí.
PÚBLICO: Es muy redundante.
DAVID: ¿Qué significa redundante?
PÚBLICO: [INAUDIBLE] desperdiciamos espacio [INAUDIBLE]..
DAVID: ¿Entonces, cuál información es redundante?
PÚBLICO: La calle [INAUDIBLE].
DAVID: Sí, tenemos mucho,
Es decir, literalmente las copié y las pegué, que en la codificación y en general
debería ser una mala señal o un mal hábito,
en especial si lo haces más de una vez.
Por eso Cambridge es idéntico, Massachusetts es idéntico,
el código postal es idéntico.
Y aun cuando esto será una pequeña mentira blanca,
puede darse el caso, de que cada código postal se asigne solo a una ciudad.
De no ser así, si tengo 02138, ¿en verdad necesito guardar Cambridge, Mass,
Cambridge, Mass, Cambridge, Mass para todos?
No, probablemente todo sea lo mismo.
De modo que, debería poder eliminar algunos de estos datos.
Y este tipo de desorden es un problema que las bases de datos pueden resolver.
Podríamos hacer esto en Excel, en las hojas de cálculo de Google, etc.
Podemos poner comillas para normalizar los datos al factorizar puntos en común.
La forma más común de hacerlo, es
empezar por asignar identificadores únicos a las cosas.
Por ejemplo, si quiero entrar aquí, me haré a mí mismo una nueva columna,
la llamaré ID.
Seré el usuario uno, Rob será el usuario dos, luego el tres
y el cuatro y así sucesivamente.
Usaremos un int para mantenerlo simple y eficiente,
porque esto solo es de 32 bits, o quizás de 64 bits,
no importa que tan largos sean los nombres de las personas, calles, etc.
Permítanme arreglar el borde para que todo se vea uniforme.
Ahora que lo he hecho.
¿Pero saben algo?, por si nunca lo han notado,
Excel, Numbers y Google soportan
muchas hojas en una hoja de cálculo.
Y solo para estar seguro, déjenme cambiarle el nombre a esto por customers.
¿Pero saben qué?
Voy a continuar en una hoja de cálculo de Google,
me daré a mí mismo otra que se llamará cities.
Y luego aquí, haré algo como esto.
Voy a almacenar aquí tal vez ah, hey, ah, digamos city y state.
Y en realidad, ¿saben qué?, ya que las ciudades que voy
voy a utilizar por ahora, se identifican de forma única por sus códigos postales,
coloquemos el código postal allí.
Y luego en esta hoja de cálculo, hagámoslo,
de manera preventiva esta vez, texto sin formato,
02138 debe ser Cambridge, Massachusetts.
Ahora, de vuelta en mi base de datos customers, ¿cuál
de estas columnas, de la A hasta la I, o esas, en realidad ya no necesitaré más?
PÚBLICO: [INAUDIBLE]
DAVID: Sí, ya no necesito esto.
Tampoco necesito esto.
Posiblemente todavía necesito el zip.
Permítanme continuar, eliminaré estos y comenzaré
a calmar su preocupación respecto a la redundancia de los datos.
Lo podría mejorar, pero al menos ahora, solo estoy guardando el código postal.
Y esto se está volviendo un poco lento.
Voy a deshacerme también de Country, y colocaré esto aquí,
para generalizar el zip code ahora será postal code.
Y esto debe ser Estados Unidos.
De modo que, mi tabla Customers ahora es mucho menos redundante.
El lado positivo es que ocupa menos espacio,
y menos espacio significa menos dinero y más espacio para otras cosas.
Eso, sin duda, es muy bueno.
Y de seguro también será mucho más fácil actualizar los datos ¿cierto?
Si alguien, si Cambridge por cualquiera que sea la razón
cambia su nombre, nuevamente a Newtown, como al parecer una vez lo fue,
solamente lo cambiaremos en un lugar, no para cada persona en la tabla Customers,
y así sucesivamente.
Así que se trata de un buen principio, ¿cierto?
Cada vez que en la codificación hicimos algo una y otra vez, o incluso en CSS,
como si tratáramos de descomponerlo.
En HTML, lo descomponemos con formatos, funciones
o mediante otras técnicas.
Este proceso de normalización se siente como algo bueno.
¿Pero saben qué?
02138, lo podemos mejorar un poco, porque eso es una cadena.
Podríamos almacenar esto como un número.
¿Saben qué es lo que voy a hacer?
En esta hoja de cálculo también tendré una columna llamada
ID cuyo valor para este city será de uno y para las siguientes ciudades
será un número arbitrario que aumentará y será único.
Ahora, lo qué puedo hacer aquí es que no es necesario almacenarlo, incluso el
02138 guion lo que sea, lo que sea, puedo solo almacenar el ID.
Ahora llamaré al zip ID, solo para que me quede súper claro
que ahora esto solo es un número.
Y al comenzar a asignar enteros únicos, arbitrarios pero consistentes a todos
nuestros datos podemos relacionarlos entre sí
al buscar un valor en el otro.
Por ejemplo, si miramos esta tabla como un humano
y vemos que, oh, David y Rob viven en el zip ID 1,
tendríamos una pregunta adicional, la cual sería, bueno, ¿qué es el zip ID 1?
Solo podemos responderla si miramos en la tabla de Cities, la revisamos,
y sería como, oh, Rob y David ambos viven en Cambridge, Massachusetts,
02138, EE.UU.
Es un paso adicional, pero también se reduce enormemente
la cantidad de datos que necesitamos, asumiendo que hay más personas en el mundo
que solo dos de nosotros y que hay millones,
miles de usuarios, o simplemente otro tipo de contexto
en el que tenemos montones y montones de datos.
Como un ejemplo de esto ¿qué recopilamos en el sitio web del curso?
es una hoja de cálculo de Google que tiene un montón de hojas.
Esto se basa en una base de datos de código abierto y acceso libre
que se parece a datos reales, pero que en su mayor parte se
tomó de una cuenta de iTunes, de la cual crearon nombres y nombres de compañías
entre otras cosas.
Como veremos, esta es una base de datos para una tienda de música
digital, como iTunes, Google Play, Spotify entre otras.
También existen diferentes entidades en el mundo de la música digital.
Tenemos nombres de álbumes y de artistas,
tenemos clientes que pueden comprar esos álbumes y escuchar a esos artistas,
también hay empleados en la compañía que vende la música,
hay géneros para esas canciones.
Porque esta es una pendiente muy resbaladiza por la cual, con el tiempo,
vamos a tener montones y montones de datos que
idealmente estarían en varios lugares a la vez, pero eso ocurre por un mal diseño.
Mantenerlos por separado es lo ideal.
Si le damos un vistazo al título de este álbum, o más bien a su pestaña,
encontraremos todos los álbumes que vende esta tienda de música digital.
Aquí están los ID exclusivos del álbum, que han
sido asignados a esos álbumes, de forma arbitraria pero permanente.
Y luego aquí están los artistas que publicaron esos álbumes.
Y la única manera de saber el nombre del artista
es por medio de Google, de hecho tendré que
desplazarme a la pestaña Artists y, OK,
aquí están los artistas y sus números.
Además, todos estos álbumes posteriores o sus canciones se asocian a géneros.
Aquí están todos los géneros y los ID asociados con ellos, entre otras cosas.
Son bienvenidos a hurgar en este tipo de datos más adelante.
Aquí están las fechas de nacimiento, por días, horas y así sucesivamente;
Hay facturas, con direcciones y las ciudades de las personas que
supuestamente compraron esta música, en la base de datos de muestra.
Sinceramente, esto se convierte muy, muy, muy rápido en algo
realmente muy molesto, ¿verdad?
Porque si nosotros los humanos deseáramos saberlo tanto, OK, ¿quién
produjo Restless and Wild?, el artista dos, ¿quién diablos fue el artista dos?
Esto no es bueno para los humanos.
Pero esto es bueno para las computadoras.
Solo necesitamos un lenguaje con el cual reconstruir lo que queremos y consultar
y cambiar lo que queremos.
Y ese es el tipo de cosas que SQL hará por nosotros.
Así que cambiaré a otra pestaña en CS50 IDE.
Encontraré la pestaña correcta aquí.
Si regreso a CS50 IDE, introduciré una herramienta llamada phpLiteAdmin.
El nombre en realidad no importa, pero esto es una herramienta que viene con el IDE,
lo descargamos gratis de la web y sencillamente lo instalé para nosotros,
eso nos permite hacer esto.
Entre la distribución de códigos de hoy tengo un archivo llamado lecture.db,
.db solo significa que es una base de datos.
El archivo también podría tener otra extensión,
pero este es uno de los estándares.
Noten eso, cerraré la consola, si hago doble clic en esto,
esto abrirá una pestaña especial en el IDE llamada phpLiteAdmin.
Lo que ahora veo es el contenido de lecture.db.
Lecture.db es un archivo binario, de ceros y unos,
eso representa una base de datos SQLite que hice antes del curso.
Así que básicamente descargué todos estos datos, e hice algunos cambios,
y después lo guardé en un archivo llamado lecture.db.
phpLiteAdmin, este GUI en la pestaña, es solo
una forma de visualizar para nosotros los humanos qué hay en esta base de datos.
Pueden ver que hay un montón de tablas, pienso que 11 tablas diferentes,
que nombré de manera idéntica a la hoja de cálculo de Google.
Este es el equivalente SQLite de la hoja de cálculo de Google.
Noten que los enlaces, no es que sean de un muy buen diseño,
pero ahora obtengo una abrumadora cantidad de funcionalidad.
Aparentemente ya tengo la habilidad de navegar por los datos, buscar datos,
insertar, exportar los datos, vaciar datos, etcétera,
que se obtienen de una base de datos.
En un momento veremos cómo hacerlo.
Si continúo y hago clic en Álbum, veré
los datos anteriores dentro de esta herramienta gráfica,
pero de nuevo solo tengo alguna funcionalidad útil.
Tengo la capacidad de editar cada uno de estos álbumes, de eliminarlos.
También puedo ver el ID del artista.
Por ahora esto no es tan útil, pero continuaré y haré esto.
Continuaré a la pestaña SQL.
Aquí es dónde esta herramienta es realmente útil,
phpLiteAdmin no es algo que introduciremos en nuestro currículum.
Esta es una herramienta que utilizaremos para visualizar lo que hay adentro
de nuestra base de datos, y se prueban dudas antes de que en realidad
se escriba en el código.
Recuerdo que una de las operaciones que SQL soporta es Select.
Permítanme intentar seleccionar una estrella del álbum.
Estas son las palabras clave de SQL.
Este es el nombre de mi tabla.
Podría citarlo, pero no es estrictamente necesario,
así que no voy a molestarme.
Y ahora si continúo y lo alejo, ¡ups!,
hacemos clic en Go, esto seleccionará para mí
todos los álbumes, en la tabla del álbum.
Ahora, esto no es tan interesante, porque hace un momento me
hice clic en el álbum de palabras y te mostré todos los álbumes.
Pero, supongo que no me preocuparé por el ID del álbum.
No me importa el ID del artista en este momento.
Continuaré con la pestaña SQL de nuevo y seleccionaré la estrella del álbum.
Pero en lugar de estrella, que era el comodín, ¿qué es lo
que querría seleccionar en su lugar?
¿Solo el nombre del álbum?
Déjenme hacer eso, Select,
oh lo siento, fue llamado Title, Title from album.
Clic en Go.
Ahora, recupero un conjunto de filas y uno de resultados, el cual se denomina,
de solo los títulos.
Ahora, de nuevo, no estoy programando, no estoy usando esta información.
Pero este es el lenguaje, la manera en que puedo expresarme en el lenguaje SQL
para recuperar solo los datos que me importan.
¿Y saben qué?
Continuaré y hare lo siguiente.
aquí es donde se vuelve más poderoso.
Si vuelvo a seleccionar todos los datos, encuentro el ID del artista.
¿Cómo obtengo el ID del artista?
Bueno, déjenme ir a artista, encuentro esa misma información, ID del artista
y a todos los nombres.
Pero aquí es donde SQL se vuelve poderoso.
Ahora puedo tomar una tabla, una de cuyas columnas
están estos números, tomo otra tabla, una en cuyas columnas
están estos números, también, y puedo unirme a ellos hábilmente
alineando los números ya que ambos son idénticos.
La sintaxis es un poco rara al principio, pero probemos esto.
Seleccione la estrella del álbum que lo une al artista.
Quiero unirme a los dos.
Pero ahora tengo que decirle a la base de datos que une las dos columnas.
Esos parecen números, pero tengo que decirle a la base de datos que
las columnas deben alinearse.
Para artista en album.ID del artista es igual a ID del artista.artista.
Esto solo es una conexión o una condición al final,
pero pueden leerlo intuitivamente.
Seleccione todo del resultado de unir álbum y artista,
que brindaron para unirlos en álbum.ID del artista,
que es la columna de ID del artista en la tabla del álbum en la columna
ID del artista, en la tabla del artista.
Eso es como hacer esto un equivalente digital.
Y si ahora sigo directo y hago clic en Go, increíble.
Ahora regreso todo de los datos reconstruidos
de una manera que es útil, porque ahora cada fila contiene el ID del
álbum y el ID del artista, pero lo más importante es el título
de la canción y el nombre del artista.
Y ahora tengo la capacidad de consultar los datos que quiero sin la ineficiencia
al almacenar todo esto junto.
Y también realmente puedo almacenarlos juntos aún en más tablas.
Notemos que esa lista, por ejemplo, está aquí en una de las tablas,
porque la tienda de música es compatible con la habilidad de hacer listas.
Aquí tenemos los ID de la lista que asigna los nombres correspondientes.
Pero, ¿cómo asociamos las canciones con una lista de reproducción?
Bueno, si una lista de reproducción solo tiene un nombre y un ID, necesitamos
una forma de asociar las canciones con una lista por medio de estos ID.
Realmente necesitamos de muchas, muchas relaciones, por así decirlo.
Y eso es lo que una base de personas nos diría.
Si queremos combinar las listas de varias personas, todos seremos
capaces de tener diferentes canciones pero tal vez de superponer canciones,
así que no podemos dedicar una canción por persona,
queremos una relación de muchos a muchos.
Si miramos el seguimiento de la lista, notemos que esta columna está loca.
Esta columna, o más bien esta tabla,
solo tiene el ID de la lista, y rastrea las pistas por medio de su ID
a una de las filas en la tabla de pistas, el ID de la lista se asigna a una de las
filas en la tabla de la lista de reproducción.
Al usar esta tabla y unirlas con varias tablas,
podemos rastrear la lista de reproducción, que son nombres de listas y de ID,
a pistas, que son nombres de canciones en ciertos álbumes.
Y con la combinación correcta de comandos, realmente puedo
reconstruir todos los datos que me importan, y en un suspiro
recuperar todos los datos y dejar que la base de datos descifre
cómo encontrar todos esas personas y todas esas canciones
y todas esas listas de reproducción de manera eficiente.
Con un CSV, tendríamos que leer cada maldito archivo de arriba a abajo
y después resuélvalo todo usted mismo.
Pero hay alguna clave de decisiones de diseño que se efectúa.
Mencioné antes que SQL no solo admite este tipo de datos,
también las restricciones representadas aquí.
Estos son solo algunos términos nuevos que ahora necesitamos como ingredientes
para diseñar una buena base de datos.
Y hemos visto uno de estos antes, Primary Key.
Resulta que, en cualquier momento en una de estas tablas
que hemos definido nosotros mismos arbitrariamente, pero con un número único,
generalmente en la columna de la izquierda, por convención, llamado ID
o denominado Artist ID o Album ID, como sea que lo llamemos,
que hemos declarado generalmente como una primary key.
Esta es una forma de decirle a la base de datos, cuando la diseñamos,
dame una tabla con una columna ID que será la clave principal.
Es decir, base de datos, te prometo que esta columna siempre será única.
Por lo tanto, base de datos, usa esto en el futuro.
Cada vez que quieras hacer algo eficiente,
confía en esa columna como único modo de identificar las filas.
No uses álbumes ni nombres o títulos de artistas
que puedan ser más largos y no únicos.
En cambio, usa eso también.
Hay otros campos que podrías marcar como únicos,
pero no tu clave principal, el número que te identifica de modo único.
En el mundo de los clientes, ¿cuál de los campos con los que jugamos
querrían probablemente que fuese único?
Y esta era nuestra pequeña base de datos de los clientes.
¿Cuáles son aquí los candidatos para tener valores únicos?
¿Atrás?
No, aquí.
PÚBLICO: teléfono.
DAVID: No.
Teléfono podría ser único, sin duda en el mundo de los teléfonos móviles.
Pero algunas personas aún tienen teléfonos fijos.
Eso podría ser algo desordenado.
Entonces tal vez, tal vez no.
¿Qué más?
PÚBLICO: ¿Nombres?
DAVID: Nombres, tal vez.
Pero si buscan en Google hay muchas probabilidades de que
muchas personas en el mundo tengan sus mismos nombres.
Y no quieren que uno de ustedes compre cosas en la tienda.
Sí.
PÚBLICO: [INAUDIBLE]
DAVID: ¿Qué dijeron?
PÚBLICO: [INAUDIBLE]
DAVID: Correo electrónico, tal vez es más probable.
Podríamos pensar en los miembros de una familia
que comparten sus correos electrónicos en casa,
lo cual complica ese escenario.
Pero tal vez.
Si ordenan que las direcciones de correo electrónico sean las mismas,
probablemente preferiría el correo electrónico al nombre, el cual
coincidiría con el de varias personas,
entonces podríamos precisar que la dirección de correo de nuestros clientes
debe ser única, porque tal vez la utilicen para iniciar sesión.
¿Cierto?
Si usan el correo electrónico como nombre de usuario, es mejor que
que sea único, de modo que no haya dos personas con contraseñas diferentes
sino con el mismo nombre de usuario o dirección de correo electrónico.
Pero una dirección de correo electrónico es un poco larga.
Malan@harvard.edu, rob@cs.harvard.
Tienen más bytes que un entero.
En resumen, podría tener sentido
identificar a sus usuarios de manera única, a fin de cuentas,
con solo un ID, un ID numérico, la clave principal.
Pero una de las características de la base de datos, es que puedes decirle,
hey base de datos, haz que esta otra columna también sea única,
y asegúrate de que yo o mis colegas nunca podamos insertar datos accidentalmente
en una base de datos que esté duplicada.
La base de datos te defenderá contra eso.
No necesitarán if y else en sus propios códigos,
pueden dejar que la base de datos lo haga por ustedes.
Mientras tanto, Index es realmente poderoso.
Pueden precisar por el índice de palabras clave, hey base de datos,
esta columna es importante para mí.
Voy a hacer búsquedas en esta columna.
Voy a buscar personas en esta columna.
Por lo tanto, continúa e indéxalo con ayuda
de tu salsa secreta que usa elegantes estructuras de datos y algoritmos sólidos
para encontrar datos de manera realmente eficiente.
Y aquí, de nuevo, nos paramos sobre los hombros de los demás.
Otros especialistas en sistemas han descubierto buenos algoritmos
y estructuras de datos, que generalmente involucran árboles,
como los que vimos hace unas semanas, que permiten encontrar datos generales
en tiempo logarítmico, no en tiempo lineal.
E igual de simple como utilizar este índice de palabras clave
veremos que la base de datos usa esos años de conocimiento
para encontrar datos más rápidamente para este pobre de mí.
No nulo.
Pueden especificar, no dejes que nulo termine en esta columna.
Debo tener un nombre de usuario.
Debo tener su número de teléfono.
No puede estar en blanco.
La clave externa es aún más elegante, pero, de hecho, ya lo hemos visto.
Cuando buscamos en estos ejemplos, en vez de en la base de datos de canciones,
notamos que en el álbum teníamos dos tipos de ID.
Teníamos el ID del álbum en la tabla asociada con los títulos,
y luego, cada uno de estos álbumes estaba asociado con el ID de un artista.
Y tenemos aquí dos palabras clave por aplicar.
Afirmo que esta es la clave principal para esta tabla,
porque identifica los álbumes de manera única.
¿Por qué es principal?
Bueno, la tabla en sí, la hoja de cálculo se llama Álbum.
Es el ID único, el principal responsable de identificar las filas.
Esa clave de allí no es principal, porque solo puede haber una,
así que se llama clave externa.
¿Pero en qué sentido es externa?
PÚBLICO: [INAUDIBLE]
DAVID: Díganlo otra vez.
PÚBLICO: [INAUDIBLE]
DAVID: Para el álbum.
Está relacionada con el álbum en el que está el artista,
pero, ¿de qué manera es externa?
PÚBLICO: [INAUDIBLE]
DAVID: Está en un archivo diferente, en una tabla diferente.
Entonces es una clave primaria en otra tabla, lo cual
es lo que la hace externa si la mencionamos en esta tabla, ¿verdad?
Estrictamente hablando, esta columna no debe estar aquí.
Podría seguir adelante y olvidarme de todos
los valores que están en esta columna resaltada.
Pero una vez que la agregue, me permite vincularla principalmente a otra tabla,
porque en este contexto se llaman claves externas.
Eso es todo en cuanto a vocabulario.
Entonces, ¿qué significa todo esto?
Ahora continuaré con phpLiteAdmin,
la cual es nuestra herramienta basada en la web para manipular datos.
Y voy a hacer lo siguiente.
Voy a cerrar esta versión de phpLiteAdmin,
volveré a mi buscador de archivos.
Y abriré una ventana de terminal solo un momento.
Entonces haré lo siguiente.
Si quiero crear un nuevo archivo en Linux, el sistema operativo que estamos usando,
pueden hacerlo muy fácilmente tocando el archivo,
incluso si no existe.
Así que toque customers.db, y noten que ahora clientes.db está a la izquierda.
Solo es un archivo vacío.
Ahora puedo, fabulosamente, darle doble clic y empezar a interactuar con él
como si fuera una base de datos.
Aún no hay ceros ni unos en él, hasta que empiece a manipularlo,
por eso dice que no hay tablas en la base de datos.
Es solo un archivo vacío.
Así que crearemos una tabla en esta base de datos, similar a lo que hice
en las hojas de cálculo de Excel o de Google.
Aquí, en esta interfaz de usuario I
puede crear una nueva mesa en la base de datos Clientes.
La llamaré mi Tabla de usuarios, porque ellos, bueno,
vamos a llamarla,
sí, Usuarios está bien.
Y en número de campos esta vez pondremos solo cuatro.
Y ahora haré clic en Go.
Y esto es lo que se obtiene de phpLiteAdmin.
Es solo una linda interfaz amigable
para, digamos, responder preguntas.
Entonces, ¿qué columnas quiero en esta tabla?
Bueno, la primera será el nombre del cliente,
o tal vez debería ser el primer nombre, entonces sería Primer nombre o P,
o como quieran llamarlo.
Lo llamaré Primero.
¿Qué tipo de datos debería tener?
PÚBLICO: Texto.
DAVID: Sí, texto.
Y entonces el apellido debe ser texto.
Pero, de hecho, me estoy adelantando.
No quiero identificar a los usuarios únicamente por sus nombres.
¿Qué decidimos?
PÚBLICO: ID.
DAVID: Sí, el ID.
Así que para mantener el orden, lo pondré primero.
Estrictamente no importa, pero es una especie de norma.
Entonces, como norma, podría llamar ID a esto.
Podríamos llamarlo ID de usuario, lo cual sería otra norma,
lo importante es mantener la consistencia.
Esto no debe ser texto sino entero.
Y fíjense en estas otras características.
Puedo decirle a la base de datos, esta es mi clave principal.
Y ningún otro campo debe ser primario.
Puedo decirle a la base de datos, te ocuparás de aumentar esto de forma automática.
No quiero hacer un seguimiento ni saber quién es cuál número.
La base de datos puede asignar una ID que aumenta de manera automática,
entonces uno se convierte en dos y con el tiempo se convierte en tres.
No nulo se da por hecho, ya que si es una clave principal no puede estar en blanco.
Y entonces esto es irrelevante, pero se pueden dar valores predeterminados.
Por ejemplo, si por cualquier razón,
la gente quisiera mantener su nombre en el anonimato, podríamos decir
que el nombre predeterminado de todos lo que están en mi base de datos
será Bob, o algo así.
Pero eso también es un poco tonto.
Tal vez queramos decir que no hay valor predeterminado, sino que nombre
y apellido no debe ser nulos, para que los usuarios cooperen y nos den
un valor.
En cuanto a la última, no sé, por ahora solo usaremos el correo electrónico.
Lo volveremos texto.
Y resulta que no podemos especificar en la base de datos
que una dirección de correo electrónico debe tener algo en algo.
Tendremos que hacerlo si alguna vez lo queremos en código.
Pero al menos puedo hacerlo no nulo.
Ahora vean lo que ocurre.
Aunque esta es una GUI, o interfaz gráfica del usuario,
cuando hago clic en Crear, me dice que esta tabla Usuarios fue creada.
Pero lo bueno de phpLiteAdmin, y por eso lo usamos,
es que también es una buena herramienta de enseñanza.
Es lo que phpLiteAdmin ejecutó para crear esta tabla.
Es una forma de aprender SQL simplemente haciendo clic, clic,
clic de manera fácil, y luego ver los comentarios de inmediato
sobre cuál comando escribieron manualmente
para crear esa misma tabla.
Y está rodeado porque es un poco largo y no está bien insertado.
Pero aquí tenemos algo muy evocador
de lo que puse antes en el tablero.
Tenemos un campo ID que es entero, esa es una clave primaria.
Y, por cierto, también debería incrementarse automáticamente.
Es una nueva función.
Pero no puede ser nula.
Aquí, el primer nombre es texto, no debe ser nulo.
El último es... no debe ser un número entero.
Eso es un error.
Debería haberlo hecho texto, entonces ahora está defectuoso.
Y luego en el correo electrónico hasta aquí hay texto, no nulo.
Entonces, ¿qué significa esto?
Bueno, les mostraré otra manera antes de usar esto en el código actual,
sobre cómo podría estar interactuando con la base de datos.
Si abro una terminal y ahora escribo esto, SQLite 3,
que es la tercera versión del programa,
Haré que esta sea mi base de datos alternativa y presionaré Enter.
Esto no es tan fácil de usar.
Tengo que saber lo que escribo, o parece que puedo escribir Ayuda para obtener ayuda.
Y estos son todos los comandos que puedo escribir en la línea de comandos.
No es tan fácil de usar.
Pero sí sé esto.
Una vez que sé SQL, puedo interactuar esto con los comandos de SQL.
Corregiré esto en mi base de datos alternativa.
No quise decir entero, así que haré este texto.
Pondré un punto y coma al final, lo cual usualmente es necesario,
aunque no siempre lo es.
Ahora presionaré Enter.
Nada parece suceder.
Pero en SQLite, si escribo Schema, es como el diseño de mi base de datos.
.schema significa, muéstrame mi base de datos.
Y cualquier comando que comience con un punto es específico de SQLite.
No es SQL, ahora es parte del lenguaje, es solo un comando local.
Oh, eso es genial.
Simplemente devuelve algo parecido a mis tablas.
Puedo verlo de otra manera.
Cerraré esto por un momento.
Y noten que ahora, en los archivos en el sitio web,
Tengo una lecture.db, que era la base de datos de música que abrimos antes.
Déjenme ver eso.
SQLite 2, lecture.db.
Pondré .schema.
Oh.
Es toda la información de la base de datos que se me volvió a mostrar como texto.
Entonces puedo respaldarla si quiero, o hacer otras cosas.
Pero echamos un vistazo a algo interesante.
Iré hasta arriba.
Y aquí tenemos, muy bien formateados, los comandos
que quienes hicieron esta base de datos en línea, de quien lo descargamos,
esencialmente crearon.
Crear tabla, Álbum.
Los corchetes son opcionales, solo son alternativas a las comillas.
Uno de los campos se llamará ID del Álbum, Título, ID del artista.
Ya hemos visto esto antes.
Uno es un número entero, otro es texto, otro es entero.
Y luego veríamos aquí estas funciones que no vimos antes.
Y les diré adiós por el momento.
Pero hay una forma de decir a la base de datos que hay una clave externa.
Se puede decir, en esta tabla hay un número que se refiere a otra tabla,
y dejar que la base de datos se asegure de que nunca puedan
agregar una ID de artista que no aplique a un artista real.
Entonces no se puede simplemente insertar artista número uno, dos, tres,
si el artista número uno, dos o tres ni siquiera existe.
Entonces, es otra función que se obtiene de la base de datos.
Y para Pset 7 solo veremos superficialmente algunos de estos.
Pero esta es una de las razones de que se gradúen en archivos
de texto y se gradúen en RAM y comiencen a usar [INAUDIBLE]
bases de datos en software como SQLite, Oracle o herramientas similares.
Quisiera saber si hay dudas antes de sumergirnos en Python.
Bien, ahora vamos a usar esto en el código.
Lo valioso de ver SQLite 3 y phpLiteAdmin
es que tengan herramientas con las cuales crear sus bases de datos
y ver lo que hay dentro de ellas sin tener
que escribir código para ambas, pues lo complica y vuelve molesto
empezar.
Entonces usaremos phpLiteAdmin para la serie de problemas siete.
Y pronto le daremos un vistazo.
Pero solo es una forma de administrar su base de datos.
De hecho no es la parte intelectualmente sustanciosa.
Para eso necesitaremos un código de Python.
Entonces abriré de nuevo mi consola.
Abriré aquí algunas pestañas.
Y entraré, digamos, en la carpeta de la lección 0 de hoy.
Y no está en línea pero pronto lo estará.
Abriré application.py y veré qué aplicación es.
Es súper simple.
Solo copia y pega muchos de los ejemplos anteriores.
Y noten que tiene una ruta diagonal, eso procesará a index.html.
Y entonces, ¿qué es ese formato?
Bueno, index.html es uno de dos archivos.
Mi diseño es una estructura genérica HTML de la página.
Index.html se ve así.
Es una gran tarea.
Así que haremos algo con este programa de la siguiente forma.
Pero primero, usemos un trampolín.
Iré a Nuevo archivo, guardaré esto como lecture.py.
Es solo un script local, nada que ver con programación web por el momento.
Y haré lo siguiente.
Primero, para aquellos que nunca habían visto Python,
python lecture.py
es un programa escrito en Python.
Si se sienten abrumados, lo hice de forma deliberada.
Es un programa de una línea.
Pero ahora podemos hacer algo mucho más poderoso.
En esencia haré lo siguiente.
En pseudo código escribo: Query database for all alumbs...
¡Ups!... albums.
For each album in database, print title of album.
Supongamos que esto es el programa que queremos escribir.
¿Cómo hago esto?
Bueno, en Python escribiré lo siguiente.
From CS50 import SQL, la biblioteca que
presentaremos nuevamente en Pset 7.
y que facilita un poco la introducción a SQL.
Y para sus proyectos finales, pueden utilizar
toda la biblioteca.
Solo es para practicar.
Y escribiré lo siguiente.
DB, para base de datos, aunque puedo llamarla como quiera,
tendrá una base de datos SQL cuyo archivo es sqlite, dos puntos,
triple diagonal, lecture, punto, DB.
Para ser más breves, esta línea de código solo dice,
hey Python, abre una base de datos SQLite que se llama lecture.db
que esté en el mismo directorio.
Eso es todo.
Después de eso, tengo una variable de Python llamada DB.
Y es una variable que me permite hablar en código con la base de datos.
Y esta es la pieza faltante.
Hasta ahora, es la única forma en que hemos interactuado con lecture.db
y lecture.db es la base de datos musical
que usa phpLiteAdmin, la cual es solo esta GUI administrativa,
o SQLite 3, que es la versión de línea de comandos de la misma.
No hemos hecho nada interesante al consultar
datos en forma de programa.
Todo lo hice manualmente.
Pero ya no más.
Ahora haré lo siguiente.
Le diré, almacena en una variable llamada Rows
todas las filas de la tabla que sean el resultado de ejecutar
select, asterisco, from album.
Así que estoy escribiendo mi código Python, pero dentro de él tengo una cadena,
y esa cadena tiene SQL en ella.
Entonces, ¿qué hago ahora si quiero implementar este pseudo código?
Esto es lo que acabo de hacer.
Ese es mi comentario.
Ahora quiero repetir cada álbum en la base de datos.
¿Cómo puedo hacerlo?
Bueno, escribo esto.
Entonces, for each album in database, escribo en sintaxis, for row in rows,
ahora, ¿qué quiero hacer?
Quiero que imprima, entonces escribo, print, row,
¿Cuáles eran las columnas en la tabla de mi álbum?
PÚBLICO: [INAUDIBLE]
DAVID: Sí, era el ID del álbum, ¿y?
PÚBLICO: [INAUDIBLE]
DAVID: Creo que fue el título del álbum uno.
Así que haré lo siguiente.
Abro y cierro comillas, creo que era Title.
Debemos ver si lo recuerdo correctamente.
Y ahora pondré también mi comentario.
Entonces tenemos un pequeño programa que solo ejecuta una consulta,
y resulta que, huy, puse una sangría excesiva... esta variable rows
contiene lo que llamamos un conjunto de resultados.
Es una lista, un arreglo, una lista de todas las filas que coinciden con esa consulta,
que, con suerte, son todas ellas.
Esto es solo el Python que vimos hace una semana o dos,
para cada fila en esa lista de filas, imprime el título de esa fila.
¿Y qué es esto exactamente?
Pueden verlo como una tabla hash o un diccionario.
Row es una de las filas
y tiene un montón de columnas.
Y la sintaxis en Python para la indexación de esas columnas
es solo la notación de corchetes cuadrados.
Esto es un dict, o un objeto de diccionario en Python.
OK.
Así que crucemos los dedos porque no estoy seguro
si nombré todo correctamente y pongo python lecture.py, Enter.
¡Uf!
Funcionó.
Lo que sale aquí son todos los títulos de la base de datos.
Déjame seguir y elegir uno.
Por ejemplo, "a soprano inspired".
Y haré otra prueba del concepto.
¿Saben qué?
No quiero obtenerlos todos.
Solo quiero seguir y llegar a WHERE, title, igual.
Y ahora usaré comillas para distinguirlo.
Entonces, ¿cuántas filas debería devolver esta consulta?
PÚBLICO: [INAUDIBLE]
DAVID: Con suerte, solo una.
Veamos.
Volveré a ejecutarlo, lecture.py.
Muy bonito.
Y ahora hay dos cosas impresas que, sin embargo,
no vimos antes porque había muchas salidas, pero que estaba allí.
Resulta que la biblioteca CS50, que les ayudará, especialmente con
siete, siempre imprime esta información de depuración que
técnicamente pueden deshabilitar.
No es parte de su programa, solo contiene información adicional.
Muestra exactamente cuál consulta se ejecutó,
lo cual será útil porque, cuando empiecen a usar la programación web,
Muy pronto, también podrán ver en su ventana de terminal
qué está haciendo su aplicación web para garantizar que
puedan diagnosticar cualquier error en su código.
Pero podemos ser más elegantes.
Recuerden que para la serie seis, o que veremos pronto en la serie seis,
si ponen import sys para un programa de Python, ¿a qué nos dará acceso,
entre otras cosas?
PÚBLICO: [INAUDIBLE]
DAVID: Sí, a los argumentos de la línea de comandos.
¿Y qué pasa si hago esto? WHERE, Title, igual, SOMETHING.
Quiero que eso venga desde la línea de comandos.
Entonces, ¿cómo puedo hacer esto?
Bueno, resulta que hay otra pieza de sintaxis
que necesitan conocer de la biblioteca CS50.
El método Ejecutar admite nombres de marcadores de posición,
donde esencialmente pueden decir, dos puntos, t, o dos puntos, title
o dos puntos, lo que quieran.
Es solo un marcador de posición.
Voy a llamarlo t, por título.
Y pueden hacer lo siguiente.
Podemos especificar que el valor de t debe ser,
por ejemplo, sys.argv, corchete, 1, la cual
ser la primera palabra que el humano escribió en la línea de comandos.
¿Y qué va a hacer Python?
Conectará esto a dos puntos t.
Eso es todo.
Es solo un marcador de posición.
Y como nota adicional, ya hemos visto esto antes.
Borraré esto solo por un momento.
Hasta hace dos minutos, la forma en la que podrían hacer esto
es con una cadena llamada f o cadena de formato, conectada.
Esto es peligroso, por las razones que veremos en un momento.
En cambio, voy a enfocarme en los dos puntos
y dejar que la biblioteca CS50 limpie o desinfecte mis datos para que
el usuario no pueda engañarme y borre accidentalmente todos mis datos.
Ahora haré lo siguiente.
Python, lecture.py... ¡ups!
Python, lecture.py.
Y ahora escribiré ese mismo título, que era,
¿Qué era? ¿una soprano?
PÚBLICO: Soprano inspired.
DAVID: ¿A soprano inspired?
¿Inspired?
Y ahora uso comillas.
¿Por qué?
PÚBLICO: [INAUDIBLE]
DAVID: Sí, es una frase.
Lo quiero todo en argv1.
No lo quiero parcialmente en argv1 y 2 y 3.
Sería un desastre.
Enter.
¡Uf!
Funcionó.
Así que ahora he escrito un programa interactivo que
toma la entrada del usuario en la línea de comandos, la conecta a la cadena SQL,
y me permite obtener los datos que realmente me importan.
Ahora, ¿por qué hice esto?
Como nota aparte, si lo hacen así, la cual habría sido nuestra técnica
hace unos minutos, antes de ver esto, esta técnica,
y de hecho ahora necesito ponerla entre comillas, dentro de la cadena SQL,
de lo contrario la biblioteca lo hará por mí,
esto es sumamente peligroso.
Está violando un principio del que, a partir de ahora,
deberían ser muy conscientes.
¿Por qué puede ser peligroso simplemente conectar el argumento
de la línea de comandos a esa cadena?
PÚBLICO: Podría poner algo malicioso o podría poner algo como [INAUDIBLE].
DAVID: Exactamente.
Puede conectar al código algo que no pretendían poner.
Permítanme volver a este punto.
¿Qué pasa si un usuario realmente malicioso no solo escribió algo
en el hermoso nombre de una canción, sino que escribió
haha, ​​punto y coma, DELETE from album, para eliminar toda la base de datos.
Esto no es realmente correcto.
De hecho no se ejecutaría correctamente.
Haha no es una palabra clave.
Pero el punto y coma significa que es para esta consulta, la eliminación del álbum
es una consulta válida que ya vimos antes, y a esto
se le conoce como un ataque de inyección SQL.
Y de hecho es muy común actualmente
porque una de las características que se obtiene de la biblioteca CS50
es la desinfección o limpieza de la entrada del usuario.
Y la recomendación es que nunca deberías
confiar en la entrada del usuario, incluso si son ustedes mismos.
Adquieran el hábito de desconfiar, incluso de ustedes mismos,
para que de ninguna manera se inyecten datos que no deberían estar en la base.
Lo demostraré de la siguiente manera.
Si entran a un sitio web de la Universidad de Yale,
su formulario de inicio de sesión se vería así.
O en la Universidad de Harvard, la clave se vería así.
Ahora revelaré cómo se ve una solicitud de contraseña
sin mostrar las viñetas, tal como es la norma,
pero en el contexto de la web, si un usuario
escribiera instrucciones aparentemente peligrosas, tal vez sucedería esto.
Supongamos que mi nombre es me@exampleprovider.com, o lo que sea,
y que mi contraseña fuera comilla, OR, comilla, uno, igual, uno.
Este no es un pensamiento completo.
Pero noten que le falta... termina con comilla aquí y le falta una acá.
Entonces es algo así como este pensamiento parcial,
porque si un adversario por ahí en internet
tratará de hackear un sistema de Harvard, Yale o similares,
pensaría que si en Harvard o Yale no fueran tan brillantes
y no desinfectaran la entrada de los usuarios, y solo confiaran en lo que sea.
tal vez el malicioso adversario, podría tratar
de completar su pensamiento, por así decirlo, de manera maliciosa.
¿Y qué significa esto?
Bueno, supongamos que el código que escribió alguien en Harvard o Yale
se ve así.
Denme variables de nombre de usuario y de contraseña
donde usen la sintaxis que empezamos a ver la semana pasada,
y verán más de esto en la serie de problemas siete.
Esto significa, averigua lo que el usuario pasó a la aplicación web,
en vez de la línea de comandos.
Y luego supongamos que el personal de Harvard o de Yale ejecutaron
SELECT, asterisco, FROM, users, WHERE, username, igual, esta cadena de sintaxis f.
Lo que es interesante aquí es que ponen las comillas correctamente
en lo que se supone que es la cadena para el nombre de usuario y contraseña.
Pero recuerden lo que el usuario iba a escribir hace un momento.
Si cierro una comilla y luego dejo otra abierta,
Puedo inyectar declaraciones arbitrarias aquí.
Y entonces un ataque de inyección SQL podría verse así.
Si escribo exactamente esos valores, me@exampleemailprovider.com,
y esa contraseña simple, vean si detectan, más allá de la rareza sintáctica,
lo que esto dice realmente.
WHERE, password, igual, comillas, lo cual
es un poco tonto si la contraseña está en blanco, o si uno, igual, uno.
Ahora, ¿cuál de estas declaraciones es obviamente cierta?
Uno es igual a uno.
Y esto es arbitrario.
Podría haber dicho fuu, igual, fuu, o cualquier otra cosa.
El punto es que, finalicé un pensamiento con esa comilla.
Luego, escribí cualquier cosa que se me antojo porque
presumo que soy algo inteligente, pero también hago suposiciones,
porque el adversario no puedo ver este código,
Solo tengo la corazonada de que, si construyo la consulta correcta, engañaré
a la base de datos para que devuelva cualquier usuario, pues uno siempre es igual a uno.
Entonces, obtendré una fila que me dejara entrar al sistema.
Sea cual sea el resultado será muy malo, a menos que desinfecten la entrada del usuario.
Entonces, este otro enfoque con el que comencé,
utilizando estas convenciones basadas en los dos puntos,
que es muy similar al %s en C,
pero que ahora es específico para SQL o para SQLite,
Lo cual garantiza ahora que cuando el usuario escriba, incluso
en la búsqueda de datos más maliciosa, la biblioteca de CS50 u otras bibliotecas
que hay en el mundo y que hacen exactamente lo mismo,
se asegurarán de que ningún carácter peligroso, como los apóstrofes,
se escapen con diagonal inversa.
Entonces, para abreviar, ni siquiera deben saber
o darle importancia a lo que es realmente un ataque de inyección SQL
si practican una buena desinfección de las bases de datos
que no se vean muy bien.
Pero es muy fácil hacerlo utilizando, en nuestro caso, la biblioteca CS50,
pero en el caso más general, con una biblioteca como esta.
Y este es un meme gracioso, ese tipo de cosas que ponen en internet,
supuestamente en el auto de una persona.
¿Qué intención creen que tiene?
AUDIENCIA: Esconder la matrícula.
DAVID: Bueno, no solo esconder la matrícula.
Seguramente es en alguna de esas ciudades donde
hay cámaras con reconocimiento óptico de caracteres para cobrar
o multar a la persona correcta, de acuerdo con su licencia
o placa.
Entonces esta persona, correcta o incorrectamente, está presumiendo
hey, tal vez sabes que en la ciudad de Cambridge
se usa un software defectuoso que no desinfecta sus entradas.
Y antes de que veamos un ejemplo web,
Sería negligente si no enseñara este cómic a una generación de
aspirantes a programadores.
[RISAS]
De ahora en adelante, si escuchan hablar sobre Little Bobby Tables,
esto es a lo que las personas de CS se refieren.
Entonces, usemos esto en un contexto web.
Ahora haré lo siguiente.
Volveré al IDE, cerraré el programa de línea de comandos
que estaba escribiendo hace un momento.
Y vamos a completar esta tarea pendiente.
Voy a regresar a application.py, la cual
no hace gran cosa por el momento.
Pero voy a proseguir y haré lo siguiente.
Voy a inicializar mi base de datos.
Y esto da SQL, igual, SQLite, dos puntos, doble diagonal, lecture.db, como antes.
Y luego, en la ruta de mi índice pondré algo como esto,
rows, igual, db.execute, el cual es el único método que necesitan saber.
SELECT, asterisco, FROM, Album.
Esto me dará todos.
Y ahora voy a pasar todas las filas a este formato.
Lo llamaré "albums" y lo pasaré por todas las filas.
Y esta es una forma de poner todas las filas y los títulos
en mi formato.
Si ahora voy a mi formato, donde tengo esta tarea pendiente,
puedo usar algo de sintaxis Jinja, la cual, honestamente, no se
profundizaremos hasta que practiquen un poco más,
pero sé por experiencia que es, for album in albums.
Ahora cerramos la llave y endfor será
como terminemos esto en mi formato de Jinja.
Y aquí voy a ir poner salidas cada vez
album, comillas, Title, y veré si no tuve algún error de sintaxis.
Ahora, iré a mi ventana de terminal
y en mi directorio fuente, en mi ejemplo de lección, pondré
flask run, para iniciar el servidor web.
Abro la URL.
¡Guau!
Esto es un desastre.
Pero parece que tiene todos los títulos, probablemente.
Limpiaré esto.
Y aquí es donde HTML se vuelve realmente útil.
En HTML, ¿cuál es la etiqueta para una lista desordenada, [INAUDIBLE]?
PÚBLICO: [INAUDIBLE]
DAVID: Sí, UL para una lista desordenada.
Entonces aquí haré una etiqueta para una lista desordenada,
pero que se cierre después de este bucle.
Voy a acomodar bien estas sangrías.
Y ahora, dentro del bucle, pondré como salida
un elemento de la lista, recuerden las semanas pasadas.
Todavía se ve súper codificado, pero, ¿qué nos dice la lógica?
En el cuerpo de mi página iniciamos una lista desordenada.
Iteramos sobre cada uno de los álbumes, y que la salida sea
su título dentro de un elemento de la lista.
Entonces, si regreso y vuelvo a cargarlo, ¿qué debería ver?
Una lista completa de los títulos de estos álbumes.
Además, puedo hacerlo mejor.
Voy a regresar y haré lo siguiente.
Ahora escribiré, q=request.args.get("q").
Y q es, de nuevo, lo que Google usa para sus consultas,
pero podría llamarlo como quiera.
Ahora escribiré lo siguiente.
Donde el título es igual a dos puntos q, y entonces déjame pasar q es igual a q.
Se ve algo chistoso, pero piensen en lo que hace.
Quiero sustituirlo colon q el valor real de q.
Y tal vez puedo ser más explícito aquí.
Si escribo query, lo que hago es pasar esto allá.
Y ahora que lo hice, ¿qué más puedo hacer?
Esta no es una aplicación web muy elegante,
pero supongamos solo quiero buscar... ¿cuál era?, la canción de soprano anterior,
Soprano Inspired.
De hecho, buscaré algo más simple.
Qué tal solo worlds.
Al estilo de hello, world.
Ahora voy a mi URL.
Y recuerden, si entendemos HTTP, podemos
poner ?... es /?=Worlds y dar Enter.
Y... diablos.
WHERE Title = Worlds :q" WHERE Title = Worlds...
¿Por qué no aparece?
request.args,
request...
Esperen un momento.
Íbamos muy bien hasta allí.
Y ahora volveré a cargarlo.
Oh, de hecho, qué buen momento...
nada.
OK, nada es algo malo.
¿Qué estoy haciendo mal?
¿Lo arruiné?
Bien, esperen.
Esperen.
Qué buen momento para presentar eprint, solo por un momento.
Volveré a cargar la página para activarla.
OK, eso es malo.
¡Caramba!
eprint no está definido desde CS50.
Oh.
Oh, estuvo cerca...
¡Sí!
OK.
[APLAUSOS]
Para ser sincero, no tengo idea de lo que acaba de suceder.
Pero funcionó.
Ahora, dejemos que estas palabras tan inspiradoras
nos hagan sentir lo que vamos a
hacer con estos ingredientes.
Hoy nos enfocamos mucho en SQL y en el diseño de la base de datos,
pero el objetivo final es utilizar estos ingredientes
y usar este nuevo lenguaje para consultar información real.
Aquí está lo que llamamos CS50 Finance, alias serie de problemas siete.
Y se les darán algunos códigos de distribución
que, en esencia, dan una interfaz de usuario similar a esto que
permite que los usuarios inicien y cierren sesión.
Pero no permite que los usuarios se registren.
Aún no permite que los usuarios compren o vendan acciones, como es el objetivo.
CS50 Finance es como construir su propio sitio web de comercio electrónico,
donde pueden comprar y vender acciones.
Pero se integrará gracias al código
que escribieron con Yahoo Finance, el cual proporciona una
aplicación de programación API muy ligera, con la que si preguntan a Yahoo
por el precio de las acciones de una tabla de cotizaciones, responderán
de modo que puedan integrarlo en su sitio web.
Entonces, lo que podremos hacer al final,
y es la solución del equipo,
es construir un sitio web como este, de modo que pueda seguir
e iniciar sesión en CS50 Finance como John Harvard, con su contraseña.
Entonces puedo ver que, de modo predeterminado, todos sus clientes,
maravillosamente, como trato especial, obtendrán 10,000 dólares virtuales.
Puedo obtener una cotización para una acción, GOOG es como G-O-O-G.
Google está en este momento en un poco más de $1,000.
Y eso es genial, porque tengo $10,000.
Entonces compraré una acción de GOOG escribiendo en el símbolo de su tabla
de cotizaciones y 1.
Y ahora poseo una parte de Alphabet, alias Google, más algo de
efectivo.
Así que implementarán todo esto y más.
Estaré muy contento de responder a sus preguntas.
Y eso es todo por hoy.
Y muchas gracias a los padres y a sus familias por asistir.
[APPLAUSE]