Sunteți pe pagina 1din 268

Introduccion a la

Programacion
para la carrera de
Licenciatura en Artes y Tecnologas

Pablo E. Martnez Lopez


Federico A. Sawady OConnor

Indice de contenidos

Introduccion

Unidad

Unidad

Unidad

Unidad

Unidad
Version digital de la
Carpeta de trabajo Unidad

Unidad

Unidad

Unidad

Pagina siguiente
2

Martnez Lopez, Pablo E.


Introduccion a la Programacion / Pablo E. Martnez Lopez y Federico
A. Sawady OConnor; con colaboracion de Carlos A. Lombardi. - 1ra ed.
- Bernal : Universidad Virtual de Quilmes, 2013.
Recurso electronico.

ISBN 978-987-1856-39-8

1.Informatica. 2.Programacion. 3.Redes. I.Sawady OConnor, Fe-


derico A. II.Lombardi, Carlos A., colab. III.Ttulo
CDD 005.3.

Procesamiento didactico: Bruno De Angelis, Ana Elbert


Diseno original de maqueta: Hernan Morfese, Marcelo Aceituno y Juan I.
Siwak
Diagramacion: Pablo E. Martnez Lopez (con LATEX)

Primera edicion: marzo 2013

ISBN: 978-987-1856-39-8

c Universidad Nacional de Quilmes, 2013 Roque Saenz Pena 352,


(B1876BXD) Bernal, Buenos Aires
Telefono: (5411) 4365 7100 http://www.virtual.unq.edu.ar

La Universidad Nacional de Quilmes se reserva la facultad de disponer de


esta obra, publicarla, traducirla, adaptarla o autorizar su traduccion y repro-
duccion en cualquier forma, total o parcialmente, por medios electronicos o
mecanicos, incluyendo fotocopias, grabacion magnetofonica y cualquier sis-
tema de almacenamiento de informacion. Por consiguiente, nadie tiene facul-
tad de ejercitar los derechos precitados sin permiso escrito del editor.

Queda hecho el deposito que establece la ley 11.723

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


3

Iconos

Leer con Atencion. Son afirmaciones, conceptos o definiciones desta-


cadas y sustanciales que aportan claves para la comprension del tema
que se desarrolla.

Para Reflexionar. Propone un dialogo con el material a traves de pregun-


tas, planteamiento de problemas, confrontaciones del tema con la reali-
dad, ejemplos o cuestionamientos que alienten a la reflexion.

Pastilla. Incorpora informaciones breves, complementarias o aclaratorias


de algun termino o frase del texto principal. El subrayado indica los termi-
nos a proposito de los cuales se incluye esa informacion asociada en el
margen.

Cita. Se diferencia de la palabra del autor de la Carpeta a traves de la


insercion de comillas, para indicar claramente que se trata de otra voz
que ingresa al texto.

Ejemplo. Se utiliza para ilustrar una definicion o una afirmacion del texto
principal, con el objetivo de que se puedan fijar mejor los conceptos.

Para Ampliar. Extiende la explicacion a distintos casos o textos como


podran ser los periodsticos o de otras fuentes.

Actividades. Son ejercicios, investigaciones, encuestas, elaboracion de


cuadros, graficos, resolucion de guas de estudio, etcetera.

Recurso Web. Liks a sitios o paginas web que resulten una referencia
dentro del campo disciplinario.

Lectura Obligatoria. Textos completos, captulos de libros, artculos y


papers que se encuentran digitalizados en el aula virtual.

Lectura Recomendada. Bibliografa que no se considera obligatoria y a


la que se puede recurrir para ampliar o profundizar algun tema.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


4

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


5

Los autores

Pablo E. Martnez Lopez


Pablo E. Fidel Martnez Lopez se recibio de Doctor en Ciencias de la Compu-
tacion en la UBA en noviembre 2005, y antes de eso de Magster en Ciencias
de la Computacion en la Universidad de la Republica. Uruguay y de Licencia-
do en Informatica en la UNLP. Ejerce la docencia universitaria desde 1990, y
desde 2007 es Profesor Asociado con Dedicacion Exclusiva en la Universidad
Nacional de Quilmes, habiendo trabajado como docente en UNLP, UBA, UNR,
UNRC y UNLM. Posee la categora 2 en el programa de incentivos a la investiga-
cion del gobierno nacional. Sus areas de interes cientfico son los Lenguajes de
Programacion, especialmente Programacion Funcional, Estructuras de Datos, la
produccion automatica de programas, la Teora de la Computacion y los Lengua-
jes formales y automatas. Ha participado en diversos proyectos de investigacion
desde 1993, habiendo dirigido incluso un proyecto de cooperacion internacional
en 2008, y varios proyectos de extension y transferencia desde 2007. Es autor
de numerosos artculos cientficos nacionales e internacionales y de un captulo
de libro. Ha formado recursos humanos en investigacion en diversos niveles, y
ha participado en tareas de gestion universitaria y transferencia de conocimien-
tos, desempenandose al momento de esta publicacion como Director de Carrera
de la Tecnicatura Universitaria en Programacion Informatica del Departamento
de Ciencia y Tecnologa de la Universidad Nacional de Quilmes (UNQ) y Direc-
tor de la Unidad de Vinculacion Tecnologica UTICs (Unidad de Tecnologas de
la Informacion y la Comunicacion) dependiente de la Direccion de Vinculacion
Tecnologica de la misma Universidad. En ambos cargos se desempena desde el
2do semestre de 2007.

Federico A. Sawady OConnor


Federico A. Sawady OConnor es Tecnico Universitario en Programacion In-
formatica de la Universidad Nacional de Quilmes (UNQ), siendo uno de los prime-
ros recibidos de dicha carrera. Ha publicado un artculo referido a la didactica de
la programacion, y su trabajo final de carrera consisitio en el contribuir en el desa-
rrollo del lenguaje G OBSTONES, disenando y desarrollando un sistema de tipos
para el mismo. Se desempena al momento de esta publicacion como empleado
de la Fundacion Sadosky en tareas vinculadas a la educacion en Computacion
y como docente de Laboratorio de Programacion I en la escuela de gestion so-
cial Florentino Ameghino de Florencia Varela, en el nivel de secundaria tecnica,
donde utiliza el enfoque propuesto en esta Carpeta.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


6

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


7

Indice general

1. La disciplina de la programacion 17
1.1. Que es la programacion? . . . . . . . . . . . . . . . . . . . . . . 17
1.2. Que son los lenguajes de programacion? . . . . . . . . . . . . . 19
1.3. Breve historia de la programacion . . . . . . . . . . . . . . . . . . 21
1.3.1. Surgimiento de las computadoras . . . . . . . . . . . . . . 21
1.3.2. Los primeros lenguajes de alto nivel . . . . . . . . . . . . . 23
1.3.3. Los paradigmas de programacion . . . . . . . . . . . . . . 24
1.3.4. Consolidacion y expansion del software . . . . . . . . . . . 26
1.3.5. La era de internet . . . . . . . . . . . . . . . . . . . . . . . 26
1.3.6. Tendencias actuales . . . . . . . . . . . . . . . . . . . . . . 27
1.4. Lenguajes para dominios especficos . . . . . . . . . . . . . . . . 28

2. Primeros elementos de programacion 33


2.1. Introduccion a elementos basicos . . . . . . . . . . . . . . . . . . . 33
2.1.1. Valores y expresiones . . . . . . . . . . . . . . . . . . . . . 33
2.1.2. Acciones y comandos . . . . . . . . . . . . . . . . . . . . . 35
2.1.3. Operaciones sobre expresiones y comandos . . . . . . . . 37
2.1.4. Tipos de expresiones . . . . . . . . . . . . . . . . . . . . . 37
2.2. Elementos basicos de Gobstones . . . . . . . . . . . . . . . . . . 38
2.2.1. Tablero y bolitas . . . . . . . . . . . . . . . . . . . . . . . . 39
2.2.2. El cabezal . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.2.3. Comandos simples . . . . . . . . . . . . . . . . . . . . . . . 42
2.2.4. Procedimientos simples . . . . . . . . . . . . . . . . . . . . 44
2.2.5. Mas comandos simples . . . . . . . . . . . . . . . . . . . . 50
2.2.6. Utilizando adecuadamente procedimientos . . . . . . . . . 53
2.3. Acerca de las cuestiones de estilo . . . . . . . . . . . . . . . . . . 58
2.3.1. Indentacion de codigo . . . . . . . . . . . . . . . . . . . . . 58
2.3.2. Eleccion de nombres adecuados de identificadores . . . . 61
2.3.3. Comentarios en el codigo . . . . . . . . . . . . . . . . . . . 63
2.4. Ejercitacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

3. Procedimientos, funciones y parametrizacion 77


3.1. Procedimientos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3.1.1. Procedimientos con parametros . . . . . . . . . . . . . . . 77
3.1.2. Formas basicas de repeticion de comandos . . . . . . . . . 83
3.1.3. Ejercitacion . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
3.2. Expresiones y funciones . . . . . . . . . . . . . . . . . . . . . . . . 87
3.2.1. Expresiones compuestas y tipos . . . . . . . . . . . . . . . 88
3.2.2. Operaciones predefinidas para construir expresiones . . . 90
3.2.3. Alternativas condicionales . . . . . . . . . . . . . . . . . . . 96
3.2.4. Funciones simples . . . . . . . . . . . . . . . . . . . . . . . 98
3.3. Funciones avanzadas . . . . . . . . . . . . . . . . . . . . . . . . . 103

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


8

3.3.1. Funciones con parametros . . . . . . . . . . . . . . . . . . 103


3.3.2. Funciones con procesamiento . . . . . . . . . . . . . . . . 105
3.4. Ejercitacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

4. Alternativa, repeticion y memoria 113


4.1. Mas sobre alternativas . . . . . . . . . . . . . . . . . . . . . . . . . 113
4.1.1. Alternativa condicional . . . . . . . . . . . . . . . . . . . . . 113
4.1.2. Alternativa indexada . . . . . . . . . . . . . . . . . . . . . . 115
4.2. Mas sobre repeticiones . . . . . . . . . . . . . . . . . . . . . . . . 118
4.2.1. Mas sobre repeticion indexada . . . . . . . . . . . . . . . . 118
4.2.2. Repeticion condicional . . . . . . . . . . . . . . . . . . . . . 121
4.2.3. Recorridos simples . . . . . . . . . . . . . . . . . . . . . . . 124
4.3. Memorizacion de datos . . . . . . . . . . . . . . . . . . . . . . . . 131
4.3.1. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
4.3.2. Recorridos mas complejos . . . . . . . . . . . . . . . . . . 140
4.4. Ejercitacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

5. Modularizacion 153
5.1. Modulos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
5.2. P YTHON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
5.2.1. Como trabajaremos con P YTHON . . . . . . . . . . . . . . . 156
5.2.2. Herramientas abstractas en P YTHON . . . . . . . . . . . . . 158
5.3. Tipos abstractos de datos . . . . . . . . . . . . . . . . . . . . . . . 160
5.4. Listas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
5.4.1. Ejercicios con listas . . . . . . . . . . . . . . . . . . . . . . 162
5.5. Diccionarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
5.5.1. Ejercicios con diccionarios . . . . . . . . . . . . . . . . . . 163
5.6. Iteracion sobre estructuras de datos . . . . . . . . . . . . . . . . . 163
5.7. Biblioteca P YGAME . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
5.8. Ejercicio integrador . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
5.8.1. Organizacion del proyecto . . . . . . . . . . . . . . . . . . . 167
5.8.2. Implementacion del juego . . . . . . . . . . . . . . . . . . . 168

6. Programacion orientada a objetos 171


6.1. El paradigma de orientacion a objetos . . . . . . . . . . . . . . . . 171
6.2. Programacion orientada a objetos en Python . . . . . . . . . . . . 174
6.3. Mas elementos del paradigma . . . . . . . . . . . . . . . . . . . . 179
6.3.1. Polimorfismo . . . . . . . . . . . . . . . . . . . . . . . . . . 179
6.3.2. Herencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

7. Bases de datos
por Carlos A. Lombardi 189
7.1. Persistencia de informacion . . . . . . . . . . . . . . . . . . . . . . 189
7.1.1. La necesidad de persistir . . . . . . . . . . . . . . . . . . . 189
7.1.2. Persistencia de datos, mecanismos de persistencia . . . . 190
7.1.3. Actualizacion, consulta, busqueda . . . . . . . . . . . . . . 191
7.1.4. Persistencia en archivos . . . . . . . . . . . . . . . . . . . . 191
7.2. Concepto de base de datos . . . . . . . . . . . . . . . . . . . . . . 192
7.2.1. Cualidades de los datos persistidos . . . . . . . . . . . . . 193
7.2.2. Desventajas de la persistencia en archivos . . . . . . . . . 194
7.2.3. Un problema de consistencia . . . . . . . . . . . . . . . . . 194
7.2.4. Que son las bases de datos? . . . . . . . . . . . . . . . . 195
7.3. Bases de datos relacionales . . . . . . . . . . . . . . . . . . . . . . 197
7.3.1. Tablas, campos y filas . . . . . . . . . . . . . . . . . . . . . 197

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


9

7.3.2. Tipos de datos . . . . . . . . . . . . . . . . . . . . . . . . . 199


7.3.3. Claves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
7.3.4. Varias tablas . . . . . . . . . . . . . . . . . . . . . . . . . . 200
7.4. Introduccion a SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
7.4.1. Estructura y ejecucion de las expresiones SQL . . . . . . . 202
7.4.2. Definiendo la organizacion de una BD . . . . . . . . . . . . 203
7.4.3. Agregado de filas . . . . . . . . . . . . . . . . . . . . . . . . 205
7.4.4. Consultas sobre una unica tabla . . . . . . . . . . . . . . . 205
7.4.5. Ordenando el resultado de una consulta . . . . . . . . . . . 209
7.5. SQL mas avanzado . . . . . . . . . . . . . . . . . . . . . . . . . . 210
7.5.1. Calculos en las consultas . . . . . . . . . . . . . . . . . . . 210
7.5.2. El valor nulo . . . . . . . . . . . . . . . . . . . . . . . . . . 212
7.5.3. Consultas sobre varias tablas . . . . . . . . . . . . . . . . . 214
7.5.4. Reuniendo mas de dos tablas . . . . . . . . . . . . . . . . . 218
7.5.5. Otras actualizaciones . . . . . . . . . . . . . . . . . . . . . 221

8. Redes 225
8.1. Redes de computadoras . . . . . . . . . . . . . . . . . . . . . . . . 225
8.1.1. Clasificacion de las redes . . . . . . . . . . . . . . . . . . . 226
8.1.2. Redes cliente-servidor y redes punto a punto . . . . . . . . 227
8.2. Modelo de capas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
8.2.1. Modelo OSI . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
8.2.2. Modelo TCP/IP . . . . . . . . . . . . . . . . . . . . . . . . . 232
8.2.3. Modelo hbrido . . . . . . . . . . . . . . . . . . . . . . . . . 232
8.2.4. Protocolos . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
8.2.5. Tipos de servicios . . . . . . . . . . . . . . . . . . . . . . . 234
8.3. Capas del Modelo OSI . . . . . . . . . . . . . . . . . . . . . . . . . 234
8.3.1. Capa de aplicacion . . . . . . . . . . . . . . . . . . . . . . . 234
8.3.2. Capa de transporte . . . . . . . . . . . . . . . . . . . . . . 239
8.3.3. Capa de red . . . . . . . . . . . . . . . . . . . . . . . . . . 240
8.3.4. Capa de enlace y capa fsica . . . . . . . . . . . . . . . . . 241
8.4. Introduccion al HTML . . . . . . . . . . . . . . . . . . . . . . . . . 242
8.4.1. Descripcion basica de una pagina web . . . . . . . . . . . 244

9. Aplicaciones 247
9.1. Interpretes y compiladores . . . . . . . . . . . . . . . . . . . . . . 247
9.2. IDEs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
9.3. Ejercicio integrador . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
9.3.1. Codificacion del modelo . . . . . . . . . . . . . . . . . . . . 250
9.3.2. Base de datos y consultas . . . . . . . . . . . . . . . . . . 251
9.3.3. Consultas a la base de datos . . . . . . . . . . . . . . . . . 254

La herramienta P Y G OBSTONES 257

Sokoban en P YTHON 261

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


10

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


11

Introduccion

La programacion es una disciplina que en pocos anos ha cobrado una relevan-


cia fundamental en diversos ambitos de la cultura humana, como la produccion
de conocimiento o de obras artsticas. Hoy da es deseable que un profesional
tenga un mnimo de conocimientos relacionados con la programacion, ya que es
factible que en algun momento del desempeno de sus tareas, se topara con la
necesidad de comprender o manipular programas, comunicarse con equipos de
programadores y tomar decisiones vinculadas a esta disciplina
La asignatura busca formar a personas con poca o ninguna experiencia en
tematicas vinculadas al desarrollo de software. Para ello ofrece una vision pa-
noramica de los temas basicos, comenzando por la historia de la programacion,
continuando con abstracciones basicas que permiten modelar programas, y pa-
sando luego a tecnicas y tecnologas avanzadas para la construccion de software
complejo, como la tecnica de programacion orientada a objetos, y tematicas de
bases de datos y redes de computadoras.
Los conocimientos impartidos durante el curso permitiran al profesional mani-
pular los conceptos asociados, para lograr un conocimiento profundo del funcio-
namiento de los medios tecnicos contemporaneos, potenciando de esta manera
la planificacion y el desarrollo de programas vinculados a su area de experien-
cia mediante su colaboracion con equipos de programacion, y permitiendole la
manipulacion de software especfico para la produccion y posproduccion de ma-
teriales graficos, sonoros, audiovisuales y multimediales en general, al conocer
los fundamentos con los que los mismos fueron desarrollados.
Se trata de una materia inicial en la carrera, pues permitira luego abordar con
herramientas cognitivas adecuadas las diversas materias especficas que cons-
tituyen el plan de estudios. Es por ello que se trata de una materia fundamental,
que no puede desconocerse.
La carpeta se organiza en 9 unidades. En la primera comenzamos presen-
tando la idea de programa y lenguaje de programacion, y haremos una revision
de la historia de los lenguajes de programacion desde su surgimiento moderno,
para comprender el rol que los lenguajes juegan la construccion del mundo ac-
tual. En la segunda hacemos la primera aproximacion a un primer lenguaje de
programacion, presentando sus elementos basicos (expresiones y comandos) y
organizandolos para comenzar a resolver problemas sencillos. Elegimos el len-
guaje G OBSTONES, desarrollado especficamente en la UNQ para la ensenanza
de un curso inicial. En la tercera continuamos presentando elementos de len-
guajes de programacion en G OBSTONES, incorporando herramientas (funciones,
procedimientos y parametrizacion) para manejar la complejidad y simplificar los
programas resultantes. La cuarta completa la presentacion del lenguaje G OBS -
TONES con una explicacion de los elementos mas complejos del mismo (estruc-
turas de control para alternativa y repeticion, y manejo de memoria elemental), y
propone algunos ejercicios avanzados. En la Unidad 5 presentamos otro conjun-
to de ideas, vinculado a la forma en que se agrupan las partes de un programa

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


12

para proveer flexibilidad (la modularizacion a traves de tipos abstractos de datos)


y comenzaremos a trabajar con estructuras de datos sencillas. Para ello cambia-
mos al lenguaje P YTHON, un lenguaje de propositos generales muy utilizado. En
la sexta presentamos las ideas de la programacion orientada a objetos, y refina-
mos a traves de ellas las ideas de modularizacion. Este estilo de programacion
es actualmente uno de los mas difundidos en la produccion de software industrial
moderno. La Unidad 7 deja el estudio de los programas en s, para concentrarse
en otro aspecto fundamental, que es la persistencia de la informacion a lo largo
del tiempo, y su organizacion a traves de bases de datos para simplicar el acceso
de los programas. Presentamos tambien nociones basicas del lenguaje SQL de
acceso a dichas bases de datos. La octava vuelve a cambiar, presentado otro
aspecto que influye en la programacion: la organizacion de redes de computado-
ras. Exploramos brevemente la forma en que se organiza la comunicacion entre
computadoras a traves de redes, volviendo a enfocar el problema de abstraccion
desde otro angulo completamente diferente. Finalmente concluimos en la Uni-
dad 9 con la presentacion de una integracion de conceptos en el desarrollo de
una aplicacion, para lo cual tambien hablamos de ambientes de programacion y
las herramientas asociadas.

Problematica del Campo


Esta carpeta presenta la programacion de una manera amena y sencilla, teniendo
en cuenta que los ususarios de la misma no buscan convertirse en expertos en el
area de la programacion, sino tener conocimientos de los fundamentos basicos
de la misma para poder interactuar en grupos interdisciplinarios que incluyan
programadores. Sin embargo, no por ello incurre en el defecto de sobresimplificar
o infantilizar la programacion a traves de metaforas u otros recursos limitantes,
sino que busca mantener una vision precisa, cientfica, sin incurrir en detalles
tecnicos innecesarios.
Articulamos la presentacion alrededor del concepto de abstraccion, idea ver-
tebral a la actividad misma de programar. La misma nocion de programacion es
una tarea abstracta, y que requiere de conceputalizaciones y representaciones
abstractas de la informacion y los procesos. Asimismo, los lenguajes de progra-
macion pueden ser vistos como herramientas de abstraccion, y los elementos
que en ellos aparecen se pueden comprender en funcion del tipo de abstraccion
que proveen.
A las unidades centradas en las formas de escribir programas le agregamos
dos unidades fundamentales, como son la persistencia de informacion a traves de
bases de datos, y la comunicacion provista por las redes de computadoras, com-
pletando de esta manera un marco conceptual integral en el proceso de desarro-
llo de software.
El material de esta carpeta esta pensado para que sirva no solo como referen-
cia y gua del aprendizaje de la disciplina, sino tambien de material de consulta
para las definiciones elementales y las ideas que son pilar de la fascinante disci-
plina de la programacion.

Reflexiones acerca del aprendizaje de la disciplina


en el entorno virtual
Las ultimas decadas fueron escenario de cambios culturales notables, dados en
gran parte por el avance de la tecnologa, y repercutieron en todos los escena-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


13

rios humanos, tanto sociales como polticos, y de produccion y transmision de


conocimentos e informacion.
El ambito educativo se ve, en consecuencia, impregnado de modificaciones,
especialmente en las formas en que es viable, hoy en da, acceder al conoci-
miento. Los cambios en las formas de comunicacion son la base sobre la que se
estructuran todos los demas cambios, a partir de la influencia en la forma en que
los individuos representamos el conocimiento y adquirimos la informacion.
Se vuelve imprescindible reflexionar sobre las herramientas que se ponen
a nuestra disposicion para adquirir conocimientos, para incorporar no solo una
practica superficial de las mismas, sino una comprension profunda sobre las po-
sibilidades e implicaciones de su uso.
En educacion es clave el protagonismo y compromiso individual de cada estu-
diante, aunque muchas veces esto no sea adecuadamente puesto en foco. En la
educacion mediante entornos virtuales esto es doblemente necesario, dado que
el docente debe reemplazar numerosas formas no verbales de comunicacion,
tales como gestos al hablar, por recursos virtuales como correos electronicos o
foros de discusion. Estas herramientas informaticas no son fines en s mismos,
y no potenciaran el proceso de ensenanza y aprendizaje si no son debidamente
explotadas. Todos los actores del proceso educativo deben adaptarse, desde una
perspectiva intrnsecamente sociocultural, a su uso de manera comoda.
En el caso de la ensenanza de la programacion, donde la practica constante
y sostenida es el unico camino para aprender los conceptos fundamentales, este
compromiso y protagonismo debe remarcarse aun mas. Parafraseando un viejo
dicho acerca de la matematica, podemos decir que la programacion no es un
deporte para espectadores (en ingles computer science is not a spectator sport),
lo que viene a decir que para poder aprender es necesario involucrarse y ejercitar,
buscar varias alternativas de solucion al mismo problema, ampliar la informacion,
y probar en forma practica en las computadoras los programas realizados. En
este proceso el docente actua como gua, y como consejero, pero el factor de
exito esta en el estudiante mismo. No dejen de tener esto en cuenta al realizar
este curso.

Mapa conceptual
El mapa conceptual de esta carpeta se presenta en el grafico G.1.

Objetivos generales de la asignatura


El curso tiene como objetivos:

ofrecer los elementos basicos de programacion, las abstracciones necesa-


rias para organizar el estado de los programas construdos, y las nocio-
nes de bases de datos y redes, mnimos necesarios para comprender el
proceso de construccion de software y sus alcances, y poder intervenir y
colaborar con un equipo de programacion en el desarrollo de programas
vinculados con la tematica de la carrera.

Un objetivo secundario del curso es ofrecer experiencia con entornos de tra-


bajo de progamacion a traves de su utilizacion en la ejercitacion. Sin embargo, no
es objetivo del curso entrenar a los estudiantes con ningun entorno especfico, ni
realizar un tratamiento exhaustivo del estado del arte en cuanto a herramientas
para programacion o utilizacion de computadoras se refiere.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


14

G.1. Mapa conceptual de la Carpeta de Trabajo

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


15

Objetivos especficos de la asignatura


Los objetivos especficos del curso son que el estudiante logre:
Conocer la historia de los lenguajes de programacion y las ideas que lleva-
ron al desarrollo y evolucion de los mismos.

Entender los elementos de construccion de progamas y su interrelacion.


Ser capaz de codificar pequenos programas para solucionar problemas
sencillos con los elementos aprendidos.
Conocer las nociones de bases de datos y redes de computadoras.

Ser capaz de construir una aplicacion sencilla que comprenda persisten-


cia de informacion y comunicacion a traves de una red (aplicacion cliente-
servidor o web).
Adquirir un vocabulario basico de terminos relacionados con la programa-
cion.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


16

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


17

La disciplina de la programacion

En esta primera Unidad comenzaremos a conocer el mundo de la programacion.


Analizaremos introductoriamente la idea de lenguaje de programacion y de pro-
grama, y veremos como surge la necesidad de contar con este tipo de lenguajes,
a partir de analizar brevemente la historia del surgimiento de los mismos.
A partir de estas nociones iniciales acerca de que trata la programacion y
del concepto de lenguaje de programacion nos prepararemos para aprender las
nociones fundamentales que todo programador maneja.

1.1. Que es la programacion?


La programacion es una disciplina que requiere simultanemente del uso de cier-
to grado de creatividad, un conjunto de conocimientos tecnicos asociados y la
capacidad de operar constantemente con abstracciones (tanto simbolicas como
enteramente mentales).
La creatividad necesaria para programar no se diferencia demasiado de aque-
lla utilizada para producir textos. Sin embargo, lo que hace a la programacion algo
especial es que requiere emplear un conjunto de conocimientos tecnicos asocia-
dos a la manipulacion de las computadoras. Esto agrega un grado notable de
rigurosidad a esta actividad, ya que no podemos programar sin tener en cuenta
este aspecto. Por otra parte, al poseer una naturaleza ligada a la resolucion de di-
ferentes problemas del mundo real, se requiere de una capacidad de abstraccion
que permita operar sin que los conocimientos tecnicos limiten al programador a
resolver adecuadamente dichos problemas.
Para Reflexionar

Ejemplos de actividades que requieren:


un uso intensivo de la creatividad son las relacionadas con el arte;
conocimientos tecnicos profundos son las relacionadas con la me-
dicina, electronica y qumica;

operar continuamente en abstracto son las relacionadas con filo-


sofa, logica y matematica.
Todas las actividades mencionadas parecen dismiles. Por que la pro-
gramacion incluye y utiliza intensamente dichas capacidades?

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


18

A lo largo de la vida los seres humanos continuamente enfrentamos todo tipo


de problemas. Para ello nos valemos de diversas herramientas, que combinadas
de maneras innovadoras amplan el espectro de soluciones y vuelven factible el
desarrollo. Los programadores se dedican principalmente a construir programas.
Leer con Atencion

Que es un programa? Un programa es una descripcion ejecutable de


soluciones a problemas computacionales, es decir, un texto descriptivo
que al ser procesado por una computadora da solucion a un problema
propuesto por los humanos. De esta manera, la parte descriptiva de los
programas es el texto que el programador le provee a la computadora. A
esta descripcion la llamaremos codigo fuente de un programa.

Definicion 1.1.1. Un programa es una descripcion ejecutable de soluciones a


problemas computacionales.

Actividad 1

Es sabido que a diario interactuamos constantemente con progra-


mas. Razone que conceptos posee actualmente sobre los programas
y contrastelos con la definicion que acaba de leer. Ademas piense:
1. que problemas solucionan los programas que utiliza a diario?
2. que diferencias existen con los problemas que no puede resolver
por medio de una computadora?

Si bien cuando escribimos el codigo fuente de un programa utilizamos smbolos


como los del lenguaje natural, este texto debe poder ejecutarse. Esa caractersti-
ca hace que los programas se diferencien de otros textos, ya que no cualquier
texto es ejecutable por una computadora. Lo que hace a un texto ejecutable es
su sintaxis dura, que no es mas que un conjunto de reglas estrictas de un deter-
La llamamos dura porque debe res- minado lenguaje de programacion, con las que se escribe el codigo fuente.
petar de manera estricta ciertas re- En sntesis, la tarea diaria de un programador es codificar, es decir, escribir
glas de formacion. En esto se dife-
rencia bastante de la sintaxis de los
programas, y dar solucion a problemas de diversa ndole. La tarea consiste en
lenguajes, donde si bien hay reglas, poder traducir las ideas que los programadores razonan a codigo ejecutable, que
existen numerosas excepciones. E es el que finalmente resolvera el problema en cuestion.
incluso cuando un texto en lengua-
je natural no respeta totalmente las Programmers have to balance two very different worlds: a world
reglas es comun que igual puede of structure and a world of imagination. They create abstract con-
ser comprendido por un lector hu- cepts using very structured programming languages (like PHP or
mano.
Java). Its not an easy task.

http://lifedev.net/2008/07/programmer-creativity-boost/

Un elemento fundamental en la codificacion de problemas en forma de progra-


mas es la representacion simbolica de la informacion: la informacion concernien-
te a un problema es representada mediante un modelo que luego se expresa a
traves de smbolos, que en el caso de los lenguajes de programacion son repre-
sentados por numeros o letras. Toda la actividad de programacion es un proceso
de codificacion y decodificacion de la informacion representada. Esta codifica-
cion/decodificacion puede darse numerosas veces antes de dar con la solucion

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


19

buscada; por ejemplo, el movimiento de los dedos en un teclado es codificado en


senales electricas que luego son codificadas como numeros, los cuales son de-
codificados como caracteres que se muestran en una pantalla codificados como
graficos, que a su vez son codificados con impulsos electricos que se traducen a
luces que el cerebro humano interpreta como los mencionados caracteres, que
resulta en lo que una persona entiende como escribir en un teclado y ver los
caracteres en la pantalla. Rara vez los usuarios de un sistema de computo son
concientes de la cantidad de codificaciones y decodificaciones que se producen
cuando utilizan computadoras. Para que los programadores puedan especificar
estas transformaciones existen lenguajes que permiten escribir estos programas.

1.2. Que son los lenguajes de programacion?


Cuando programamos, no podemos utilizar el lenguaje natural con que nos comu-
nicamos cotidianamente los seres humanos. Por el contrario, los programadores
emplean un lenguaje que la computadora puede interpretar para realizar tareas.
En otras palabras, un lenguaje de programacion.
Una idea fundamental en la programacion, que no es nativa de esta disci-
plina, pero que es donde se aplica con mayor rigor, es la composicionalidad, o
sea, la capacidad de entender algo como una composicion de partes, y tratar
cada parte por separado; y si alguna de las partes es demasiado grande, re-
petimos el procedimiento! Por ejemplo, una ciudad se compone de barrios, los
cuales estan compuestos de manzanas, las cuales estan compuestas de casas,
que a su vez estan compuestas de ladrillos, y podramos continuar hasta llegar
a las partculas mas elementales (los quarks?). En las disciplinas tradicionales,
cada parte es estudiada por una especialidad diferente. En nuestro ejemplo, la
lnea de trabajo para disenar una ciudad posee urbanistas, arquitectos, etc. hasta
fscos subatomicos. . . Cada disciplina, entonces, aborda un nivel y a lo sumo se
relaciona con los dos adyacentes en estas jerarquas conceptuales. En la progra-
macion, en cambio, es la misma disciplina la que aborda el tratamiento de todos
los niveles de la jerarqua, desde los bits hasta los sistemas hechos con cientos
de miles de componentes complejos. Esta particularidad de la programacion fue
senalada por el cientfico de la programacion Edsger Wybe Dijkstra, que es con-
siderado por muchos como uno de los fundadores de la computacion moderna Se pronuncia etsjer
por sus trabajos fundacionales en programacion estructurada y algoritmos y por wbe daijkstra. Fue
un cientfico holandes
sus opiniones sobre como debe hacerse y ensenarse la programacion. En su que vivio entre 1930
trabajo Sobre la crueldad de ensenar realmente ciencias de la computacion, el y 2002. Pionero en
dice que esta nocion es una de las novedades radicales de la computacion, lo el desarrollo de las
que la hace algo sin precedentes en la historia de la ciencia y la humanidad. ciencias de la compu-
tacion y ganador de
Para Ampliar numerosos premios
por sus notables contribuciones a
la programacion.
Realice una busqueda en internet acerca de la figura de Edsger
Dijkstra, y considere algunas de sus contribuciones y las ideas que
manejaba. Comience por leer el artculo On the cruelty of really tea-
ching computing science y profundizar sobre la idea de novedad radical.

.
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/
EWD1036.html

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


20

Para Ampliar

Entre las historias que se cuentan sobre Edsger Dijkstra hay una carac-
terstica de su personalidad que se reflejo en todos sus trabajos. Intente
descubrir cual es.

Lo mas notable de esta novedad radical reside en el hecho de que la base de


la jerarqua de programacion es la unica que tiene sustento en el mundo fsico.
Esta constituda por los circuitos que conforman las computadoras. Sobre es-
ta capa se construyen las abstracciones mentales que permiten imaginarse que
el movimiento de energa en los circuitos representa numeros y cuentas entre
ellos, y que al encender diversas luces se conforman imagenes que pueden, a
su vez, representar casi cualquier cosa: ventanas y botones en el caso de
las interfases graficas, dragones y armas en el caso de los juegos, palabras
y dibujos en el caso de las herramientas de oficina como los procesadores
de palabras. Con esta abstraccion de la circulacion de energa pueden hacerse
cuentas de maneras sumamente veloces lo cual permite resolver problemas de
mayor complejidad, simular inteligencia al realizar deducciones mecanicamente,
controlar mecanismos diversos, preparar sistemas que reaccionen a cambios en
el entorno, y un sinnumero de etceteras; en sntesis, todas las maravillas mo-
dernas a las que estamos tan acostumbrados y que hace 100 anos atras eran
apenas una fantasa casi utopica.
Los programadores, entonces, tenemos que aprender a imaginarnos cosas
inexistentes, dotarlas de estructura y volverlas reales a traves de los programas.
Y las herramientas que nos permiten llevar esto a cabo son los lenguajes de
programacion.
Leer con Atencion

Un lenguaje de programacion es una serie de reglas que establecen


que descripciones seran aceptadas y ejecutadas y cuales no tienen
sentido para el mecanismo de ejecucion provisto por la computadora.
Ademas, estas reglas estan disenadas de manera composicional, para
que sea sencillo construir programas de mayor envergadura.

Definicion 1.2.1. Un lenguaje de programacion es un conjunto de reglas que


permiten escribir programas para su ejecucion por cierto mecanismo.
Existen muchos y variados lenguajes de programacion, de caractersticas su-
mamente diferentes y que emplean diferentes enfoques con los que podemos
programar. Cada lenguaje comprende un conjunto de ideas que guan, como su
proposito final, la forma en que codificamos la descripcion que otorgaremos a la
Esta forma viene dada por las re- maquina. En todo momento el lenguaje de programacion permite especificar de
glas que definen como se combi- manera precisa el trabajo que el programador espera que la computadora realice.
nan los elementos que el lenguaje
de programacion provee al progra- Para Reflexionar
mador.

Conoce o escucho el nombre de algun lenguaje de programacion?


Sabe el lenguaje de programacion con el que se desarrollo algun pro-
grama que use a diario?

A su vez, algunos lenguajes de programacion permiten volcar mejor las ideas


abstractas que el programador intenta emplear. Estos se conocen como lengua-
jes de alto nivel, ya que intentan, con cierto grado de eficacia, soslayar aquellas

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


21

tareas que la computadora requiere realizar para que el programa cumpla con
sus objetos. Pero existen tambien lenguajes de bajo nivel, que nos hacen definir
en mayor o menor medida cada paso que el programa seguira, y por ende, estan
ligados a la naturaleza operacional de la maquina. Esta denominacion surge de
la idea de imaginar que la computadora es la base fundacional sobre la que los
programas ejecutan, y que las ideas abstractas se van construyendo sobre ellas.
Hablaremos entonces de un nivel alto de abstraccion cuando nos estemos refi-
riendo a abstracciones mas cercanas a las ideas del problema a ser solucionado,
a la mente de los programadores; y de nivel bajo de abstraccion cuando nos re-
firamos a abstracciones mas cercanas a las ideas relacionadas a las formas de
funcionamiento de las maquinas que ejecutan los programas.
Definicion 1.2.2. Un lenguaje de programacion de alto nivel es uno que expre-
sa mejor las ideas en las que debe pensar el programador, y en alguna forma
esta mas alejado (y menos dependiente) de la maquina especfica que ejecu-
tara cada programa escrito en dicho lenguaje.
Definicion 1.2.3. Un lenguaje de programacion de bajo nivel es uno que expresa
mejor las ideas propias de los mecanismos de ejecucion, por lo que es mas
dependiente de la maquina especfica que ejecutara cada programa escrito en
dicho lenguaje.
El desarrollo de los lenguajes de programacion es guiado fundamentalmente por
la busqueda del nivel de abstraccion adecuado para poder expresar con facilidad
cierto tipo de soluciones a los problemas a resolver. Podra decirse que los len-
guajes de progamacion surgieron y se desarrollaron a partir de la necesidad de
reconciliar dos mundos: el mundo operacional o fsico, relativo a la ejecucion de
bajo nivel de las computadoras; y el mundo denotacional o abstracto, definido por
las ideas que manejan los programadores. Esto impactara tambien en la forma
en que pensamos programas. Por eso conviene revisar un poco la historia de la
programacion.

1.3. Breve historia de la programacion


En este apartado vamos a contar una breve (y no particularmente precisa) histo- Alan Mathison Turing
fue un matematico,
ria de la programacion, con el objetivo de tener un panorama de como se clasifi-
logico, criptoanalista
can los lenguajes modernos, y como esto influye en la forma en que se piensan e informatico ingles
programas. Nos limitaremos a hablar de la parte moderna de la historia, des- que vivio entre 1912
de el surgimiento de las computadoras con valvulas y circuitos hasta nuestros y 1954. Famoso por
desarrollar las ideas
das, omitiendo la prehistoria de las maquinas de calcular, teoras fundaciona- de algoritmo y de
les, etcetera. computacion, determino los lmites
de la computabilidad, o sea, de la
capacidad de resolver problemas
1.3.1. Surgimiento de las computadoras mediante algoritmos. Es considera-
do el padre de las ciencias de la
Las computadoras como las conocemos actualmente surgieron durante la pri- computacion.
mera mitad del siglo XX. En 1936, Alan Turing desarrollo la idea de maquina de
computo universal a traves de sus maquinas de Turing, que fueron los primeros
dispositivos teoricos en contar con la nocion de un programa, o sea un dato que
se le suministraba a la maquina y que afectaba su comportamiento. Turing inten-
taba resolver el problema de decodificar los mensajes del ejercito aleman durante
la guerra, y se enfrentaba con el problema de que su equipo no era lo suficien-
temente veloz para resolver el problema a tiempo, a pesar de que las bases de
calculo eran sencillas. De ah que penso en utilizar maquinas para acelerar el
proceso, y desarrollo la teora necesaria para tales maquinas.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


22

A partir de los trabajos de Turing, John von Neumann desarrollo una arqui-
Se pronuncia yon fon tectura de maquinas que usaban la misma memoria para almacenar los datos
noiman. Matematico y los programas. La arquitectura von Neumann, o alguna variante de la mis-
hungaro-americano,
que vivio entre 1903 y
ma, es aun hoy utilizada por, practicamente, todas las formas de computadoras
1957. Realizo nume- existentes.
rosas contribuciones Estos dos descubrimientos permitieron, durante la Segunda Guerra Mundial
en matematicas, pero
su nombre se conoce
el desarrollo practico de las primeras computadoras: los trabajos del aleman Zu-
por su aporte a la arquitectura de se, los trabajos ingleses en la lnea Colossus y los trabajos americanos en la
las computadoras. lnea ENIAC.
Recien en la decada de 1950 se comenzaron a producir computadoras a nivel
comercial. Estaban basadas en tubos de vaco llamados valvulas y eran enor-
mes y costosas, y su poder de computo era menor que el de un telefono digital
moderno. Sin embargo significaron una revolucion en terminos de calculo para
la epoca. Fueron la llamada primer generacion de computadoras. La segunda
generacion aparece a fines de esa decada, cuando las valvulas son reemplaza-
das por transistores, y permiten iniciar la carrera para disminuir el tamano de las
computadoras. Las computadoras de la segunda generacion son mas pequenas
y consumen menos electricidad que las anteriores.
Durante la decada de 1960 se invento el circuito integrado, que fue la clave
para el desarrollo del microprocesador, que dio lugar a la tercera generacion.
Los circuitos integrados son pastillas de silicio en las que se colocan miles de
componentes electronicos en una integracion en miniatura.
Para Ampliar

Para saber mas sobre el desarrollo del hardware, especialmente las pri-
meras computadoras, consultar:

Se suele decir que este lenguaje,


compuesto solo de 0s y 1s, cons- http://en.wikipedia.org/wiki/Computer_history
tituye la base fsica de la jerarqua
conceptual de los programas. Sin y tambien
embargo, este lenguaje es en reali-
dad una abstraccion que expresa
la presencia o ausencia de algo a
traves de 2 numeros y de combi- http://es.wikipedia.org/wiki/Generaciones_de_computadoras
naciones de los mismos, aunque
el hecho de que esta tambien sea
una abstraccion, practicamente no
se tiene en cuenta al considerar las
Todas estas computadoras iniciales se programaban en lenguaje binario, o sea,
abstracciones provistas por los len- a traves de lo que de manera abstracta se denominan ceros y unos, y que en
guajes. realidad en esa epoca eran agujeros (o su ausencia) en tarjetas perforadas. Con
este lenguaje binario se codificaban instrucciones para indicar las acciones que
las maquinas intentaban llevar adelante. Los primeros lenguajes de programa-
cion reemplazaban entonces estas cadenas de 0s y 1s por palabras mas faciles
de recordar (instrucciones mnemonicas) como MOVE, LDA, ADD, etc., las cua-
les constituyeron la primer abstraccion sobre la capa fsica. La relacion entre las
instrucciones mnemonicas y el codigo binario era directa: por cada mnemonico
exista una instruccion en binario y viceversa. As se construyen los primeros tra-
ductores que traducen instrucciones mnemonicas a binario; recibieron el nombre
Si intentamos ser precisos, no se de ensambladores, y se convirtieron en los primeros lenguajes de programacion
trata de un lenguaje, sino de un ti- de computadoras de la historia.
po o familia de lenguajes. Pero es
comun referise a esta familia como Cada computadora vena con su propio lenguaje ensamblador (assembly lan-
si se tratase de un lenguaje unico. guages en ingles), y cada programador deba aprenderlo junto con las carac-
tersticas especficas de la maquina en cuestion. Pero programar en assembler
requera tremendos esfuerzos intelectuales y era muy facil cometer errores, pues-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


23

to que haba que atender todos y cada uno de los aspectos de las maquinas que
se programaban, los cuales no eran pocos ni simples. Ademas, al querer reali-
zar un programa para otra computadora deba aprenderse todo el lenguaje de
nuevo desde el comienzo. El problema es que el lenguaje assembler se acerca
mas a la forma de operar de las computadoras y no a la forma de pensar de los
programadores; o sea, en los terminos que manejamos en esta Unidad, es un
lenguaje de muy bajo nivel. En ese momento era necesario este tipo de manejo
de bajo nivel, puesto que los recursos de los que dispona una computadora eran John Warner Backus
extremadamente escasos y deban, por lo tanto, ser administrados con precision fue un cientfico
americano de la
y sumo cuidado. computacion que
vivio entre 1924 y
2007. Gano diversos
premios por sus con-
tribuciones, entre las
que se encuentran
1.3.2. Los primeros lenguajes de alto nivel la creacion del primer lenguaje de
programacion de alto nivel, y de
un mecanismo de descripcion de
La situacion con los lenguajes ensambladores era bastante preocupante para lenguajes de programacion conoci-
los programadores de aquella epoca pues les restaba productividad, les res- do hoy como forma Backus-Naur
tringa la creatividad y el espectro de soluciones imaginables. Por esa razon, (Backus-Naur Form, o BNF).
en 1955, John Backus y sus colegas de IBM desarrollaron, en el campus de
esta compana en California en Estados Unidos, el lenguaje FORTRAN, por
FORmula TRANslator (o mas detalladamente, the IBM Mathematical F ORmula
T RANslating System), que es tpicamente considerado por toda la comunidad in-
formatica como el primer lenguaje de programacion independiente de la maqui-
na. FORTRAN introdujo muchas ventajas sobre los lenguajes ensambladores, e Tecnicamente el primer lengua-
hizo mas claras las operaciones basicas. je de programacion de este esti-
lo fue P LANKALK UL (pronunciado
La idea rectora en esos das era hacer la programacion mas cercana al len- plankalkil), desarrollado por Kon-
guaje natural humano; o dicho de otro modo, aumentar el nivel de abstraccion. rad Zuse en 1943 en Alemania. Sin
embargo, debido a la Guerra, este
Por esa razon, estos lenguajes que empezaron a surgir fueron denominados len-
lenguaje no fue hecho publico has-
guajes de alto nivel. Hoy en da se los suele entender como lenguajes de mas ta 1972.
bajo nivel, puesto que existen otros lenguajes (como los lenguajes funcionales o
los orientados a objetos) que son de mayor nivel de abstraccion que los aqu men-
cionados. En esta epoca el motor que llevaba adelante las investigaciones y el
desarrollo de software eran las aplicaciones de defensa y las de administracion a
gran escala.
Al poco tiempo de la aparicion de FORTRAN surgieron otros dos lengua-
jes: LISP (por LISt Processor, procesador de listas), antecesor de los modernos
lenguajes funcionales y COBOL (por COmmon Business Oriented Language,
lenguaje orientado a los negocios comunes) que fuera adoptado en bancos, com-
panas y dependencias oficiales. En menos de una decada florecieron otra do-
cena o mas de lenguajes diferentes. Cada uno de estos lenguajes se enfocaba
en cierta forma de resolver problemas, siendo la mayora orientados a establecer Entre los mas notorios que die-
una secuencia de instrucciones con foco en diferentes aspectos de como esta- ron origen a ideas modernas estan
blecer la comunicacion entre las diferentes partes que componan el programa. CPL (antecesor de C), S IMU -
LA (precursor de la progamacion
Un lenguaje que resulto un hito por la consolidacion de muchas ideas al res- orientada a objetos), y BASIC (ori-
pecto de como deban definirse los lenguajes de programacion fue ALGOL (por ginalmente disenado para la en-
senanza).
ALGOrithmic Language, lenguaje de algoritmos). Este lenguaje fue de gran in-
fluencia en muchsimos lenguajes modernos, puesto que sus ideas siguen usando-
se en el diseno actual de lenguajes de programacion (por ejemplo, la forma de
describir sus reglas de sintaxis, la Backus-Naur Form o BNF, se sigue usando
en la especificacion de la sintaxis de todos los lenguajes de programacion mo-
dernos). Tambien fue el primer lenguaje para el que se estudio como asignar
significado (semantica) de manera independiente a la ejecucion.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


24

1.3.3. Los paradigmas de programacion


Durante la decada de 1960, la proliferacion de lenguajes de programacion si-
guio creciendo, y de a poco fueron diferenciandose grupos o familias de lengua-
jes, en torno a la predominancia de ciertas caractersticas. Estos grupos dieron
origen a lo que se denomina paradigmas de progamacion, que no es otra cosa
que un conjunto de ideas y conceptos al respecto del estilo con el que se expre-
san las soluciones a problemas a traves de un lenguaje de programacion. Cada
paradigma privilegia ciertas ideas por sobre otras, y ciertas formas de combina-
cion por sobre otras, dando lugar a estilos muy diferentes (aunque muchas veces
complementarios) en la forma de programar.
Definicion 1.3.1. Un paradigma de programacion es un conjunto de ideas y con-
ceptos vinculados a la forma en que se relacionan las nociones necesarias para
solucionar problemas con el uso de un lenguaje de programacion.

Para 1970 ya se pueden identificar cuatro grandes paradigmas, que estan vi-
gentes hoy da y que son claramente reconocidos por todos los miembros de la
comunidad informatica. Mucho despues se intento identificar paradigmas adicio-
nales a estos cuatro originales, pero no hay consenso sobre si alguno de ellos
llega o no a poder ser considerado un paradigma y merece ese nombre; por esa
razon nos limitaremos a hablar de los cuatro paradigmas principales.
El foco del desarrollo de software se fue desplazando hacia la educacion,
para poder formar a los futuros programadores. La administracion a gran escala
siguio teniendo fuerte presencia, pero las aplicaciones orientadas a la defensa
fueron disminuyendo.
Los cuatro paradigmas de programacion que surgieron a fines de los sesenta
y principios de los 1970, y que resultaron de fundamental influencia en la forma
de hacer programacion, son:
el paradigma imperativo,
el paradigma orientado a objetos,
el paradigma funcional, y
el paradigma logico.
Los dos primeros estan mas orientados a la forma de manejar estado y podran
ser denominados procedurales, mientras que los dos ultimos estan mas orienta-
No es usual asociar el termino pro- dos a expresar conceptos o nociones independientes del estado, y podran ser
cedural con los lenguajes orienta- denominados declarativos. El paradigma que se desarrollo con mayor mpetu al
dos a objetos, pero es una forma
de indicar que los mismos se con-
principio fue el imperativo, debido a su cercana con los lenguajes de bajo nivel.
centran mas en el estado que en la Los otros tardaron mas tiempo en adoptar un estado de madurez, y no fue hasta
descripcion de informacion. mediados de la decada de 1980 que tanto el paradigma funcional como el logico
y el orientado a objetos empezaron a ser foco de atencion masiva.
Dentro del paradigma imperativo se clasifican lenguajes mas vinculados con
la secuencia de instrucciones y cercanos al assembler. Algunos nombres nota-
bles que surgieron en esa epoca dentro del paradigma imperativa, y aun cono-
cidos hoy en da, son: BASIC, desarrollado en 1965 por John Kemey y Tho-
mas Kurtz con la intencion de que se conviertiese en un lenguaje de ensenan-
za; PASCAL, creado, tambien con fines didacticos, por Niklaus Wirth en 1970
a partir del ALGOL; y C, disenado por Dennis Ritchie y Ken Thompson en los
laboratorios Bell (Bell Labs) entre 1969 y 1973, con el proposito proveer una tra-
duccion eficiente a assembler y permitir la administracion eficaz de los recursos
de computo de las maquinas con arquitectura von Neumann a traves de abs-
tracciones cercanas al bajo nivel, que brinda una forma comoda e independiente

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


25

de la computadora de administrar sus recursos. La fama del C se debe a que,


por esta caracterstica de su diseno, fue utilizado en la programacion del sistema
operativo UNIX y fue ampliamente portado a numerosos sistemas. Es uno de los
lenguajes mas difundidos y conocidos de todos los tiempos, y su estudio implica Actualmente el nombre UNIX es
un conocimiento profundo de la forma en que se ejecutan las computadoras. una marca registrada que se li-
cencia para usar cuando un sis-
Para Ampliar tema operativo cualquiera satisfa-
ce sus definiciones. La denomina-
cion UNIX-like (de tipo UNIX)
Para saber mas sobre sistemas operativos, su funcion, su historia y su se utiliza para referirse a una
clasificacion, consultar la Wikipedia: gran familia de sistemas operati-
vos que se asemejan al UNIX ori-
ginal. La familia UNIX-like tiene di-
versas subcategoras, entre las que
se encuentra el actualmente popu-
http://en.wikipedia.org/wiki/Operating_system
lar GNU/L INUX.

Dentro del paradigma funcional se clasifican lenguajes orientados a la descrip-


cion de datos, de su forma, las relaciones entre ellos, y sus transformaciones. Si
bien inicialmente no fueron tan populares, la investigacion llevo a este paradigma
a la madurez y desde el mismo se realizaron grandes aportes a todos los len-
guajes modernos. Algunos lenguajes que surgieron en esa epoca dentro de este
paradigma son: ML, desarrollado por Robin Milner y otros a principios de los se-
tenta en la Universidad de Edimburgo en el Reino Unido con el proposito de servir
para desarrollar tacticas de prueba en herramientas de demostracion automatica
de teoremas. Se trataba de un lenguaje con un sistema de tipos estatico, siendo
esta una de sus grandes innovaciones; y S CHEME, derivado como dialecto de
LISP por Guy L. Steele and Gerald J. Sussman en el laboratorio de inteligencia
artifical del MIT, siguiendo principios de minimalidad en la cantidad de conceptos
distintos a proveer, pero conservando un gran poder expresivo.
Dentro del paradigma orientado a objetos se encuentran lenguajes que agru-
pan el codigo alrededor de la metafora de objeto, y que intentan representar
mediante datos encapsulados las entidades del mundo real. Al ya mencionado
lenguaje S IMULA, pionero de los lenguajes orientados a objetos, se le agrego el
lenguaje S MALLTALK, creado en el Learning Research Group (LRG) de Xerox
por Alan Kay y otros, tambien en los setenta, pensado con fines educacionales
basandose en la teora constructivista del aprendizaje. Fue la base del desarrollo
posterior en tecnologa de objetos, que hoy es uno de los pilares de la construc-
cion moderna de software.
Finalmente, dentro del paradigma logico se encuentran distintos lenguajes
orientados a la descripcion de las relaciones logicas entre aserciones, que ha-
bilitaban la posibilidad de realizar inferencias y ciertas formas de razonamien-
to automatico, lo cual fue la inspiracion para desarrollar el area conocida como
inteligencia artificial. El lenguaje mas conocido de este paradigma, que tambien
surgio a finales de la decada de 1970 en Marseille, Francia, en el grupo de Alain Usualmente es definida como el
Colmerauer, es P ROLOG, un lenguaje basado en la afirmacion de hechos y reglas estudio y diseno de agentes inteli-
gentes, donde un agente inteligen-
de inferencia, que se utiliza mediante consultas en la forma de afirmaciones que te es un sistema que decide sus ac-
deben ser validadas a partir de los hechos. ciones con base en su entorno de
Cada uno de los lenguajes mencionados dejo un sinnumero de descendientes manera de maximizar sus chances
de exito. Existen numerosos sub-
y practicamente todos los lenguajes modernos se vinculan, de una forma u otra,
campos dentro del campo de la in-
con alguno de estos. teligencia artificial y los mismos no
Otro gran avance de esta epoca fue el desarrollo de lo que dio en llamarse siempre estan vinculados, siendo
programacion estructurada, que sucedio dentro del paradigma imperativo, y con- los mas exitosos los vinculados a
la optimizacion y busqueda de in-
sistio fundamentalmente en aumentar la abstraccion de los lenguajes, eliminando formacion compleja.
primitivas de control desestructurado, o sea, que permitan moverse libremente
por el codigo, sin tener en cuenta su estructura logica. En este avance es cuando

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


26

se establecen las formas fundamentales de combinacion de componentes que


veremos en esta carpeta.

1.3.4. Consolidacion y expansion del software


Durante la decada de 1980 todos estos lenguajes y paradigmas comienzan un
proceso de consolidacion y de combinacion, que dan origen a nuevos lengua-
jes hbridos entre paradigmas, refinan y estandarizan los lenguajes existentes, y
sintetizan todo lo aprendido en nuevos lenguajes. Ademas, diversos grupos de
investigacion y desarrollo se comprometen con la implementacion de compilado-
res y herramientas para ayudar en el proceso de construccion de software, dando
lugar a numerosos avances en el campo de la implementacion de lenguajes.
En este perodo surgen ademas las computadoras personales, actualmente
conocidas como PC, que invaden los hogares y empujan el desarrollo de tecnicas
de programacion a mucha mayor escala. Por ejemplo, la provision de interfases
graficas utiles y eficientes, de sistemas de oficina personales, el desarrollo de jue-
Son lenguajes basados en scripts,
que a su vez son pequenos progra-
gos, la administracion de pequenas empresas (que antes no podan permitirse la
mas escritos con la intencion de au- administracion computarizada por sus costos altsimos), etc. Esto dio origen a lo
tomatizar tareas de mantenimiento que actualmente se conoce como la industria del software, a traves del desarrollo
en ambientes de software, y que de empresas dedicadas exclusivamente a la produccion de software.
originalmente estaban ideados pa-
ra ser corridos a mano por el admi- En esta epoca surgen lenguajes como C++, que es un derivado del C al
nistrador del sistema. que se le agregan nociones de programacion orientada a objetos; P ERL, un
lenguaje de scripting pensado para hacer reportes en sistemas U NIX; T CL (pro-
nunciado tece-ele, o tambien tkl), otro lenguaje de scripting para tareas de
prototipacion de interfaces graficas, el cual se suele combinar con el toolkit de
interfaces T K, combinacion conocida como T CL /T K; y E RLANG, un lenguaje fun-
cional y sistema de ejecucion desarrollado por la empresa Ericsson para construir
aplicaciones de tiempo real tolerantes a fallos.
Hacia el final de este perodo la comunidad de programacion funcional desa-
rrolla el lenguaje H ASKELL, que sintetiza los conocimientos de todos los lenguajes
del area, y establece un estandar para el paradigma funcional, sentando las ba-
ses para la investigacion de nuevas caractersticas. Este lenguaje, que es (junto
con S MALLTALK en el paradigma de objetos) uno de los pocos lenguajes com-
pletamente puros con capacidad de desarrollo a nivel industrial, tiene la par-
ticularidad de haber sido desarrollado por un comite representativo de toda la
comunidad funcional, encabezado por John Hughes y Simon Peyton-Jones. Es,
en la opinion de muchos investigadores de lenguajes, uno de los lenguajes mas
solidos conceptualmente, y nos atreveramos a decir, uno de los lenguajes de
mas alto nivel entre los existentes actualmente y de los mas adecuados para
ensenar conceptos avanzados de programacion. Ademas ha sido el soporte de
numerosas investigaciones que desarollaron la teora necesaria para enriquecer
a muchos otros lenguajes.

En ingles free software, pero usan- 1.3.5. La era de internet


do free en el sentido de libertad (co-
mo en free will, libre albedro), y no
en el sentido de gratuidad (como en
La decada de 1990 marco la difusion de Internet, que constituyo una platafor-
free beer, cerveza gratis). Si bien el ma completamente nueva para el desarrollo de los sistemas de computadoras.
software libre puede ser gratuito, la Esta nueva forma de comunicar computadoras dio lugar a numerosas evolucio-
libertad tiene que ver mas bien con nes, de las cuales los lenguajes de programacion y el desarrollo de software no
la posibilidad de conocer y modifi-
car el codigo fuente de los progra- estuvieron ausentes.
mas. Una evolucion importante que se dio en este perodo fue la gran difusion de
la idea de software libre, que aunque no tiene que ver con la parte tecnica de
los lenguajes en s, impacto en la forma de hacer software y sistemas. Durante

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


27

la expansion de las PC de la decada de 1980 las empresas de software vendan


el derecho de usar los ejecutables de los programas (practica que muchas em-
presas aun mantienen), pero no de conocer el codigo fuente de los mismos. De El ejecutable es un programa en
esta manera, cualquier modificacion que debiera ser hecha en el codigo deba una forma que puede ser ejecuta-
do por una computadora especfi-
esperar a que la empresa fabricante dispusiese recursos para ello. Esta es una ca, pero que no es normalmente
forma de disponer del derecho de autor para limitar el uso del codigo produci- entendible por las personas
do. En esa epoca surgio tambien la idea de utilizar el derecho de autor de otra
manera, para permitir la inspeccion y modificacion del codigo fuente, siempre y
cuando se respetase la autora original. Esta idea evoluciono en los noventa en
muchas formas de licenciamiento diferentes.
Para Ampliar

Investigue sobre el concepto de software libre, sobre como el mismo fue


producto de las formas de licenciamiento, sobre las variantes existentes
de licencias y sus caractersticas, y sobre las profundas consecuencias
sociales de esta idea.

La posibilidad de inspeccionar y modificar el codigo, sumado a la amplsima red


de comunicacion que proveyo Internet, permitio desarrollar comunidades alrede-
dor de ciertos sistemas de software, dando lugar a desarrollos como el siste-
ma operativo GNU/L INUX, el navegador Mozilla, la suite de oficina OpenOffice y
muchsimas otras.
Esta ampliacion de la cantidad de gente en condiciones de programar, junto
con nuevas formas de utilizar las computadoras a traves de internet, favorecio la
aparicion de nuevos lenguajes. En este perodo el mayor motor de avance fue
la abstraccion de las operaciones en la web y el desarrollo de aplicaciones que
aprovechasen Internet.
En esta epoca surgen lenguajes como P YTHON, un lenguaje que combina los
paradigmas orientado a objetos, imperativo y en menor medida, funcional; RUBY, Una maquina virtual es un progra-
un lenguaje dinamico y con capacidad de modificar su propio codigo basado en ma que simula ser una computado-
P ERL y S MALLTALK; y PHP, un lenguaje de scripting originalmente pensado para ra que ejecuta programas. Su prin-
producir paginas web dinamicas. Sin embargo, los lenguajes que alcanzan real- cipal objetivo es despreocupar al
programador de muchas de las ca-
mente mayor difusion son J AVA, un lenguaje desarrollado por la empresa Sun ractersticas especficas que posee
Microsystems que deriva su sintaxis de los lenguajes C y C++ incorporando no- la computadora real en donde final-
ciones de objetos al estilo S MALLTALK, y con la principal caracterstica de correr mente correran sus programas.
sobre una maquina virtual; y J AVASCRIPT (que no debe ser confundido con J A -
VA ), un lenguaje de scripting basado en prototipos combinando caractersticas de
los paradigmas imperativo, orientado a objetos y funcional, y cuya utilizacion es
basicamente en la construccion de paginas web, al ser combinado con el lengua-
je HTML de especificacion de formato en dichas paginas.

1.3.6. Tendencias actuales


El siglo XXI continuo viendo el desarrollo de la programacion, e incorporo a
la comunicacion en Internet (que continua en expansion) el motor producido
por el desarrollo de juegos, la telefona movil, el surgimiento de la idea de la
nube digital, la animacion cinematografica, y actualmente la Television Digital.
Siguieron apareciendo lenguajes de la mano de grandes empresas. Se pue- alojan en sus servidores desde los
den mencionar C# y F# de la plataforma .NET de Microsoft, y los lenguajes DART datos de los usuarios hasta las apli-
caciones con los que los mismos
y G O de la empresa Google. Tambien surge S CALA, que se diseno para misma son modificados, y permiten que
la maquina virtual de J AVA, e incorpora nociones del paradigma funcional a dicho cualquier persona mantenga en un
lenguaje. unico lugar su informacion.
Tambien se desarrollaron numerossimas lneas de trabajo, como ser la es-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


28

tandarizacion (dando lugar a desarrollos como Unicode, que es un estandar para


la codificacion de textos o el lenguaje extendido de descripcion de documentos,
XML), la integracion de sistemas (diferentes lenguajes incorporan la capacidad
de ser combinados en el mismo programa, diferentes herramientas como bases
de datos pueden ser accedidas desde casi cualquier lenguaje, etc.), las aplica-
ciones en programacion concurrente, paralela y masivamente paralela (que per-
miten el mejor aprovechamiento de los recursos computacionales), desarrollos
en seguridad de la informacion herramientas como firewalls, antispams, antivi-
rus y muchas otras, pero tambien la incorporacion de nociones de seguridad en
los lenguajes), investigaciones en codigo movil, computacion de alto desempeno,
programacion orientada a aspectos y muchsimos etceteras.
Para Ampliar

Para hacerse una idea de la cantidad de lenguajes que existen, sus


influencias relativas entre ellos y su clasificacion segun paradigmas
puede observarse el grafico G.1.1, donde se muestran los lengua-
jes en un grafo de tipo galaxia, donde se agrupan por paradigma
y grupos dentro de los paradigmas (indicados por color), con las
conexiones a los lenguajes que influenciaron y su tamano relati-
vo a su influencia. El original de este grafico puede encontrarse en:

http://griffsgraphs.com/2012/07/01/
programming-languages-influences/

Cerramos este apartado con la certeza de que la proxima decada nos depa-
rara nuevas sorpresas en el desarrollo de sistemas de computacion.

1.4. Lenguajes para dominios especficos


Todos los lenguajes descritos en los apartados anteriores tenan la particularidad
de ser lenguajes de propositos generales (GPLs, por su sigla en ingles, General
Purpose Languages) y como vimos, la intencion fue siempre abstraer de una
forma u otra el modelo de computacion subyacente.
Ahora bien, para poder cumplir con este proposito (abstraccion con gene-
Un lenguaje declarativo es un len- ralidad), estos lenguajes ofrecen una amplia gama de herramientas y formas
guaje orientado a la descripcion de de combinacion. Esta amplitud resulta ser demasiada en ocasiones, cuando los
soluciones minimizando los com-
ponentes de ejecucion que se ex-
propositos son mas particulares (como por ejemplo acceso a una base de datos,
plicitan. Se asocian tpicamente a composicion de textos, descripcion de paginas web, etc.), sobre todo teniendo en
los paradigmas funcional y logico cuenta que los usuarios que busquen utilizarlos seran especialistas de dichos do-
y, debido a su capacidad de expre- minios. Por esta razon surgieron otro tipo de lenguajes, orientados a abstraer las
sar computos paralelos de manera
implcita, han cobrado mucha rele- nociones e ideas de un dominio particular de trabajo. Estos lenguajes se conocen
vancia recientemente. como lenguajes especficos de dominio (DSLs, por sus siglas en ingles, Domain
Specific Languages). Son normalmente lenguajes altamente declarativos, y en
muchos casos extremadamente pequenos, adecuados solamente para una tarea
muy especfica, que tanto pueden ser considerados lenguajes de programacion
como lenguajes de especificacion.
Cada dominio particular tiene asociado uno o mas lenguajes disenados te-
niendo en cuenta las ideas de dicho dominio, y sus particularidades, abstrayendo
lo necesario y no mas que eso. Existe un estilo de programacion que sostiene
que para cada problema debe crearse un DSL particular para resolverlo, siendo

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


29

G.1.1. Galaxia de los lenguajes de programacion, segun paradigma e influencia

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


30

esto parte del proceso propuesto para la solucion de problemas; este estilo se
suele denominar programacion orientada a lenguajes. Existen numerosas inves-
tigaciones sobre la manera mas eficiente y efectiva de definir nuevos lenguajes
rapidamente y se han desarrollado numerosas herramientas para ello.
En este apartado mencionaremos dos o tres de los dominios mas populariza-
dos, y relevantes para el publico general, pues una cobertura exhaustiva resulta
Puede resultar interesante investi- practicamente imposible e innecesaria para los objetivos aqu propuestos.
gar mas en el tema, eligiendo un El primero de los dominios que consideraremos es el de consulta y administra-
dominio de su interes y comproban-
do si existen DSLs para dicho domi-
cion de bases de datos. El modelo tradicional utiliza bases de datos relacionales,
nio. que son agrupaciones de datos en vnculos (o relaciones) dadas por el proble-
ma a modelar. Para describir las consultas a este tipo de bases de datos, IBM
en 1970 desarrollo un DSL denominado SQL (por su denominacion en ingles,
Structured Query Language). Es uno de los DSLs mas conocidos hoy da. Este
Son lenguajes textuales que permi-
lenguaje evoluciono con el tiempo, y dio lugar a diversos lenguajes de proposito
ten anotar un documento con tags general como F OX, C LIPPER, RBASE y los lenguajes asociados a los motores
que sirven para especificar estruc- de bases de datos Oracle e INFORMIX. Todos los lenguajes de esta familia se
tura, agregar significados asocia- denominan grupalemente como 4GL (Lenguajes de Cuarta Generacion).
dos a diferentes elementos, asociar
informacion de autora, revisiones, Otro dominio muy conocido es el de diseno y especificacion de contenidos pa-
etcetera. ra la Web. En este dominio el lenguaje mas conocido es HTML, un lenguaje de
marcado (markup language) que permite especificar los elementos de una pagi-
na web de manera tal que diferentes herramientas puedan elegir como mostrar-
los. Como otros lenguajes de marcado especifica informacion a traves de etique-
tas, mas conocidas por su denominacion en ingles, tags. Los tags son utilizados
Esta palabra tambien se utiliza en para describir estructura, informacion visual, comportamiento u otras nociones,
castellano como anglicismo aun no y son interpretados por las diferentes herramientas que analizan un programa
aceptado por la Real Academia Es-
panola.
en uno de estos lenguajes para decidir diferentes cursos de accion. Por ejem-
plo, en el caso de HTML, los diferentes navegadores pueden elegir mostrar los
elementos de diferentes maneras dependiendo de factores tales como el tipo de
dispositivo (pantalla de PC, telefono, etc.), las opciones elegidas (ver el codigo
fuente o mostrar el resultado) y otros. Por eso se dice que HTML es un lenguaje
de marcado presentacional. Otro DSL asociado al dominio de presentacion web
es el CSS, por el ingles Cascading Style Sheets (hojas de estilo en cascada),
utilizado para especificar el estilo de presentacion de una familia de documentos
de manera generica.
Otro DSL que se clasifica dentro de los lenguajes de marcado es el XML,
por eXtensible Markup Language (lenguaje de marcado extensible), que se uti-
liza para definir un conjunto de reglas de codificacion de documentos en un for-
mato que es simultaneamente legible por las personas y por las computadoras.
Aqu los tags se utilizan para expresar la estructura del documento, sus partes
y dependencias, y en ese sentido se puede considerar como un lenguaje de
marcado descriptivo. Los documentos descritos con XML estan correctamente
formados por definicion, siendo imposible la especificacion de documentos con
partes faltantes o incompletos. El lenguaje es extremadamente flexible, pudiendo
utilizarse para describir metadatos, o sea, documentos que describen, de mane-
ra completamente formal y susceptible de ser analizada por las computadoras,
la forma de los datos o documentos a definir con el mismo lenguaje XML. Una
de las formas mas conocidas de este tipo de descripciones es llamada DTD,
por Document Type Definition (definicion de tipo de documento), un conjunto de
tags XML especficamente disenado para describir formatos de documentos. Del
XML evolucionaron otros lenguajes tales como RSS, ATOM, SOAP, and XHTML
(una version de HTML basada en las definiciones de XML).
Un tercer dominio, aunque por el momento solo difundido en la comunidad
cientfica (mas especficamente entre matematicos, fsicos e informaticos), es el
de composicion tipografica (en ingles, typesetting). En este dominio existe un len-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


31

guaje de marcado extremadamente poderoso y flexible llamado LATEX, utilizado


para la preparacion de documentos de altsima calidad de presentacion con mni- Pronunciado latex en castellano,
mo esfuerzo. LATEX es la parte frontal del languaje TEX, un lenguaje de marcado pero tambien leitek o leitej en el
idioma ingles.
para typesetting pero de mas bajo nivel. La forma de trabajo propuesta por es-
te lenguaje difiere de manera radical de la filosofa WYSIWYG (What You See
Is What You Get, lo que ves es lo que obtenes) promovida por las herramien-
tas como MS-Office y OpenOffice, permitiendo concentrarse mas en la estructu-
ra del documento que en su presentacion o composicion tipografica, aportando
eficiencia y flexibilidad con mnimo esfuerzo. Si bien la curva de aprendizaje de
este lenguaje es elevada al inicio, una vez que se alcanza un cierto grado de Es una forma de definir el esfuerzo
familiaridad la productividad se multiplica exponencialmente, permitiendo escri- requerido para aprender cierta no-
cion en funcion del tiempo requeri-
bir libros con la misma facilidad con la que se escriben documentos cortos. En do y los resultados obtenidos. Una
particular esta carpeta de trabajo fue disenada de manera completa utilizando curva elevada indica que hace fal-
LATEX. Existen extensiones de LATEX para escribir presentaciones (similares a las ta mucho esfuerzo en poco tiempo
de MS-Powerpoint, pero con la filosofa LATEX), paginas web (permitiendo traducir para obtener buenos resultados.
a HTML u otros DSLs para ese proposito) y documentos con contenido especfi-
co de numerosos dominios (como matematicas, qumica, informatica y muchos
mas).
Otro dominio es el desarrollo de lenguajes de programacion, donde se de-
finen herramientas conocidas analizadores sintacticos, utiles a los disenadores
de lenguajes de programacion. Para este proposito existen lenguajes basados
en las gramaticas BNF y utilizados en herramientas como YACC, B ISON, y una
multitud de derivados.
Para terminar enumeramos algunas de los lenguajes y herramientas mas co-
nocidas en diversos dominios: P OSTSCRIPT (para descripcion de paginas para
impresion y publicacion electronica), M ATHEMATICA (para manipulacion simboli-
ca en areas cientficas y de ingeniera), VHDL (para especificacion de hardware),
L OGO (para ensenanza de programacion en niveles iniciales), CS OUND (para es-
pecificacion de sonidos), lenguajes para procesamiento de imagenes, lenguajes
de reescritura de grafos, de trazado de grafos, lenguajes para descripcion de
diagramas, y muchos, muchos otros.
Actividad 2

Puede determinar si existe algun DSL para su area de dominio? Por


ejemplo, edicion de videos, construccion de guiones cinematograficos,
edicion grafica, etcetera. Si existe, investigue sobre las caractersticas
de dicho lenguaje.

Para Ampliar

Puede complementar lo visto sobre la historia de la programa-


cion con un resumen visual en el video que se puede encontrar en:

http://programandoenc.over-blog.es/article-28741792.html

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


32

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


33

Primeros elementos de
programacion

Para empezar a entender la programacion primero debemos abordar los lengua-


jes de programacion. Y para entender esos lenguajes debemos entender primero
los distintos elementos que podemos encontrarnos cuando construimos o leemos
o miramos un programa. En esta unidad vamos a empezar a conocer los bloques
elementales que conforman cualquier lenguaje de programacion.

2.1. Introduccion a elementos basicos


Los lenguajes de programacion estan compuestos por distintos elementos, que
se relacionan en el codigo de distintas maneras. Estos elementos y sus rela-
ciones son similares a las que podemos encontrar en textos escritos en codi-
gos lingusticos ya conocidos, como los lenguajes naturales, con la unica dife- Estas formas basicas quizas apa-
rencia que poseen cierta precision adicional en su definicion. Por ejemplo, en rezcan combinadas o distorsiona-
una oracion en castellano podemos encontrar sustantivos, adjetivos, verbos, etc., das en diferentes lenguajes de pro-
gramacion, pero entendiendolas se
combinados con ciertas reglas. En los lenguajes de programacion vamos a en- pueden entender las formas com-
contrar expresiones, comandos, etc., tambien combinados con ciertas reglas. plejas. Esto es igual que en los len-
Una forma de empezar a entender un lenguaje de programacion, es primero guajes naturales.
entender cuales son las formas basicas de estos elementos. Es importante vol-
ver a remarcar que cada elemento en programacion esta definido de una manera
rigurosa en la que no se admite ningun tipo de ambiguedad, como s puede su-
ceder en el idioma castellano.

2.1.1. Valores y expresiones


El primero de los elementos comunes a la mayora de los lenguajes de progra- Puede entablarse una analoga en-
macion son los valores. Estos pueden representar numeros, colores, nombres tre las expresiones y los valores, y
las palabras del espanol y las ideas
de personas, numeros de telefono, por ejemplo. Como puede observarse, estos o conceptos a los que hacen refe-
elementos representan datos, que los programas manipulan y transforman. rencia. Ademas, las palabras tam-
bien se forman a traves de smbo-
Definicion 2.1.1. Un valor es una entidad o dato con sus caractersticas propias. los, que especificamente son letras
del abecederio mas otros signos
Ejemplos de valores son el numero dos, el color rojo, el nombre de mi to Arturo, lingusticos. Y as como las ideas
son necesariamente expresadas a
etcetera. traves de palabras, los valores en
Sin embargo, para hablar o escribir valores sin ambiguedad, se utilizan otros los programas deben ser descritos
elementos llamados expresiones, que son la forma en que se describen valores. a traves de expresiones.
Las expresiones estan formadas por smbolos y cadenas de smbolos, y requie-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


34

ren una interpretacion para entender que valor describen.


Leer con Atencion

En sntesis, las expresiones son la forma en que los valores se mani-


fiestan en el codigo fuente de los programas, y los valores son aquellos
conceptos o ideas que dichas expresiones referencian.

Definicion 2.1.2. Una expresion es un smbolo o cadena de smbolos que se


utiliza para describir, denotar o nombrar un valor especfico.
La idea de denotar puede ser nueva o poco conocida. Por eso creemos conve-
niente definirla.
Definicion 2.1.3. Denotar algo es referirse de manera especfica a eso, distin-
guirlo de otros de manera unica. Segun el diccionario es significar.
Por eso usamos denotar como sinonimo de describir, aunque estrictamente no
lo sea: cuando describimos algo, estamos refiriendonos a ello, significandolo. En
este sentido es que se dice que las expresiones denotan valores.
Para Reflexionar

Por ejemplo, existen infinidad de formas posibles de describir al nume-


ro cinco: numeros arabigos (5), numeros romanos (V ), la cara de un
dado ( ), con fosforos en el truco ( ), operaciones compuestas con
numeros (3 + 2), y muchas otras. Observa la diferencia entre las distin-
tas expresiones, y el valor cinco? Se da cuenta que con cualquiera de
ellas, una persona que conoce el metodo de intepretacion de un smbolo,
puede identificar al valor referido?

Ejemplos de expresiones tal como apareceran en un programa, junto con una


descripcion en castellano del respectivo valor que denotan, son:
Expresion Valor
2 numero dos
5 numero cinco
4+1 numero cinco
Rojo color rojo
"Arturo" nombre de persona

Observar que las expresiones pueden tener formas basicas, atomicas (como
5), o pueden estar formadas por partes (como 4+1), y sin embargo se refieren al
mismo valor. En ese caso, se suele decir que las expresiones son equivalentes,
y por ende pueden ser intercambiadas a eleccion.
Para Reflexionar

Cuantas formas equivalentes de describir al valor 5 usando numeros


y sumas puede imaginarse? Reflexione sobre la diferencia entre una
expresion cualquiera y el valor que describe.

Esta idea de valor de los lenguajes de programacion se puede ver tambien en


las interfases de los programas que implementan herramientas graficas, como
editores de texto, etcetera. En dichas herramientas informaticas aparecen valo-
res, aunque las expresiones que se usan para describir estos valores adoptan

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


35

G.2.1. Ejemplos de valores en el programa Open Office

diferentes formas (conos, texto, etc.). En el grafico G.2.1 podemos visualizar dis-
tintos valores, y la forma en que aparecen graficados en un programa (el editor
de textos de Open Office). En el ejemplo, los valores son el tipo de la fuente, el
tamano de la fuente, el color de la fuente, y un texto con la palabra Texto. Todos Es un programa libre, de fun-
estos valores aparecen de una forma u otra en el codigo que los programadores cionalidad similar a otras herra-
mientas no libres, como Word.
de dichas herramientas escriben. Para conocer esta herramien-
Actividad 1 ta en mayor profundidad, ver

Trate de identificar otros valores que aparecen mostrados en el Open


Office. Elija otro programa de uso tradicional (por ejemplo, una planilla http://www.openoffice.org/es/
de calculo, un editor de graficos, etc.), y trate de identificar valores que
aparezcan graficados en los mismos.

Las expresiones que podemos utilizar cuando codificamos programas, su forma


exacta y la forma en que podemos manipularlas dependeran del lenguaje de pro-
gramacion que estemos utilizando. Las reglas que rigen estas formas (y otras) se
conocen como sintaxis del lenguaje de programacion. La sintaxis normalmente
consiste en reglas rgidas que hay que aprender para cada lenguaje. Al aprender
un lenguaje de programacion deben aprenderse todas las reglas de sintaxis de
cada uno de los elementos, en combinacion con que cosas describe cada uno de
ellos (su significado o semantica). Volveremos sobre este punto mas adelante.
Por otra parte, dependiendo del tipo de programa con el que trabajamos, los
valores seran en mayor o menor medida el centro de atencion. Por ejemplo, de
tratarse de un sistema de facturacion, los datos registrados por el programa seran
de suma importancia, y su correcta conservacion representa el objetivo del mis-
mo. Por el contrario, un programa de edicion de videos se centrara principalmente
en transformar informacion para producir un producto final, siendo los valores in-
dividuales menos relevantes.

2.1.2. Acciones y comandos


Sin embargo, no toda idea es un valor. En muchas situaciones simplemente des-
cribir datos no alcanza para que los programas resuelvan problemas. Por esta
razon, los programas tambien describen acciones, que son la manera de pro-
ducir efectos o consecuencias operacionales sobre diversos elementos, general-
mente externos a los programas. Por ejemplo, existen programas que manipulan
maquinas en fabricas, impresoras, fotocopiadoras, etc. o que reproducen image-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


36

G.2.2. Ejemplos de acciones en el programa Open Office

nes y sonidos sobre dispositivos audiovisuales, y tambien los programas tradi-


cionales como editores de texto o planillas de calculo, que modifican archivos,
imprimen documentos, etc. Todos estos programas estan produciendo efectos
sobre el mundo, a traves de modificar los elementos sobre los que operan.

Definicion 2.1.4. Una accion es la manera de producir un efecto sobre un ele-


mento u objeto del mundo, ya sea interno o externo al programa en s.

As como los valores se manifiestan en los lenguajes de programacion a traves


de las expresiones, las acciones son descritas mediante comandos. Lo que dis-
tingue a los comandos de las expresiones es la idea a la que hacen referencia.
Mientras las expresiones referencian cosas (abstractas o concretas), los coman-
dos referencian acciones (formas de producir efectos). Pero tanto expresiones
como comandos estan formados por cadenas de smbolos. Ejemplos de coman-
Existen lenguajes en donde se pue- dos, con su respectiva accion, tal como podran aparecer en algunos programas,
de distinguir visualmente cuando son:
una cadena de smbolos se tra-
ta de una expresion o un coman- Comando Accion
do, haciendo que uno empiece con
MostrarEnPantalla muestra un dato por pantalla
minusculas y otro con mayusculas
por ejemplo; pero esto no es un re- EliminarCarpeta elimina la carpeta seleccionada de nuestro disco duro
quisito esencial y en muchos len- ApagarComputadora apaga la computadora que estemos utilizando
guajes estas construcciones pue- ImprimirArchivo ordena a la impresora que imprima un archivo
den manifestarse bajo la misma for-
ma, e incluso combinadas.
EnviarMail enva por correo electronico el texto que redactamos

Definicion 2.1.5. Un comando es una cadena de smbolos que describe una


accion especfica.

De la misma forma que los valores, las acciones tambien se encuentran gra-
ficadas en los programas tradicionales. En el grafico G.2.2 podemos visualizar
distintas acciones encontradas en el programa Open Office.
La mayora de los lenguajes de programacion trabajan con comandos. Al igual
que con las expresiones, la forma exacta en que se construyen comandos co-
rresponde a la sintaxis del lenguaje, y se rige por las mismas reglas rgidas, que
como se menciono, son una de las cosas a aprender al estudiar un lenguaje
de programacion. En el caso de los comandos, su significado (su semantica) es
normalmente entendida a traves de la forma en que la maquina que ejecuta el
programa lleva a cabo las acciones correspondientes. Esto se conoce como com-
portamiento operacional del comando, y es comun no distinguir entre el comando
como descripcion de la accion y la accion en s. Sin embargo, en algunos casos
es fundamental hacer esta distincion, y por ello es importante conocerla.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


37

Leer con Atencion

Un comando no es mas que un texto que describe una accion, y como


tal, no hace nada; solo describe lo que se pretende que una maquina
haga. Sin embargo en el lenguaje cotidiano solemos decir que, por ejem-
plo, el comando GrabarArchivo graba el archivo, y no que describe la
accion de grabar el archivo.

Para Reflexionar

Reflexione sobre la naturaleza de los comandos como cadenas de


smbolos, y sobre el hecho de que la misma accion puede llegar a des-
cribirse de diferentes maneras. Por que cree que abusamos del len-
guaje diciendo que un comando hace la accion, cuando en realidad solo
la describe? Medite cuantas veces en el lenguaje cotidiano no somos
exactos con lo que decimos, y sin embargo nos entendemos, y tambien
cuantas veces ese abuso del lenguaje nos conduce a equvocos.

2.1.3. Operaciones sobre expresiones y comandos

De asignaturas de matematica es sabido que podemos realizar operaciones so-


bre distintas expresiones. Por ejemplo, los numeros pueden ser sumados, resta-
dos y multiplicados; las palabras pueden ser concatenadas (puestas una a con-
tinuacion de las otras); y los colores pueden ser combinados para formar otros
colores. A todas estas operaciones que utilizan expresiones para resultar en otras
expresiones las denominaremos operaciones sobre expresiones. El resultado de
una operacion sobre expresiones es siempre una nueva expresion, y por lo tanto
puede volver a combinarse. Entonces, podemos escribir (2 + 3) 4 combinando
la expresion 2 + 3 con la expresion 4 a traves de la operacion de multiplicacion.
Nuevamente, las reglas de sintaxis de un lenguaje establecen que operaciones
son posibles sobre cada expresion, permitiendo de esa forma conocer el total de Cada lenguaje tiene sus propias
las expresiones del lenguaje. estructuras de control. En el len-
guaje que aprenderemos en bre-
Los comandos tambien pueden ser combinados mediante operaciones. En ve veremos las formas mas basi-
el caso de los comandos, las operaciones se suelen conocer con el nombre de cas de las mismas, que combina-
estructuras de control. Por ejemplo, dos comandos pueden ponerse uno a con- das son extremadamente podero-
sas. Sin embargo el repertorio de
tinuacion del otro para indicar que luego de terminar la accion descrita por el estructuras de control es amplsimo
primero de ellos, debe llevarse a cabo la segunda accion; esta estructura de con- y debe prestarse atencion en cada
trol se conoce como secuenciacion. La sintaxis de un lenguaje tambien establece lenguaje.
las posibles estructuras de control y su significado.

2.1.4. Tipos de expresiones

Los valores son parte de distintos conjuntos. Por ejemplo, el numero dos for-
ma parte de los numeros naturales, las palabras forman parte del conjunto de
todas las palabras y los colores forman parte del conjunto total de colores. De-
nominaremos tipo de una expresion a un conjunto de expresiones determinado,
y lo denotaremos mediante algun nombre especial. Diremos, por ejemplo, que la
expresion 2 posee tipo Numero, y el color Rojo posee tipo Color.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


38

Expresion Tipo
Rojo Color
"Casa" Palabra
2+4 Numero
Norte Direccion

G.2.3. Ejemplos de expresiones con sus tipos

Actividad 2

De seis ejemplos mas de expresiones utilizando como gua los tipos


dados como ejemplo en el grafico G.2.3

Para Reflexionar

Cual puede ser la utilidad de los tipos en un lenguaje de programacion?


Piense sobre que podra significar Rojo+Norte, o "Casa"*"Auto".

Cuando veamos el conjunto de operaciones sobre expresiones, en la unidad 3,


subapartado 3.2.1, veremos la utilidad que le daremos a los tipos en esta Carpeta
de trabajo. Sin embargo, los tipos son utiles en varias formas, que exceden com-
pletamente el alcance de este curso. Por otra parte, existen lenguajes con tipos y
sin tipos, y dentro de los que utilizan tipos, las construcciones e ideas varan de
lenguaje en lenguaje. Pero incluso en su forma basica, los tipos representan una
ayuda importante a la hora de pensar un programa.

2.2. Elementos basicos de Gobstones


Para ejemplificar todas las nociones explicadas hasta el momento, y comen-
zar a aprender un lenguaje de programacion, utilizaremos un lenguaje llamado
G OBSTONES, que nos permitira entender estos conceptos basicos de programa-
G OBSTONES fue disenado e imple- cion en profundidad, antes de pasar a conceptos de mayor complejidad.
mentado por docentes de la UNQ G OBSTONES es un lenguaje conciso de sintaxis razonablemente simple, orien-
con el unico proposito de servir co-
mo lenguaje inicial para aprender a tado a personas que no tienen conocimientos previos en programacion. El len-
programar. guaje maneja distintos componentes propios ideados con el fin de aprender a
resolver problemas en programacion, pero al mismo tiempo intentando volver
atractivo el aprendizaje, para lograr captar la atencion y capacidad de asombro
del estudiante.
Cada concepto relacionado a G OBSTONES sera definido de una manera mas
estricta que la que habitualmente encontraramos en otras disciplinas.
Para Reflexionar

A que cree usted que se debe la necesidad de ser estrictos, particula-


ridad de la programacion? Intente relacionarla con la unidad 1, en el que
explicamos la naturaleza de la programacion. Piense especficamente
en la necesidad de que los programas ejecutan de manera automatica
muchas de las tareas que realizan, sin intervencion del usuario en estos
casos.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


39

El lenguaje G OBSTONES es el conjunto de reglas de sintaxis y su significado


asociado, pero para poder efectivamente ejecutar programas G OBSTONES, hace
falta contar con alguna herramienta informatica que lo implemente. Actualmente
existen dos herramientas, una basica construda utilizando el lenguaje de pro-
gramacion Haskell, denominada sencillamente G OBSTONES por haber sido la
primera, y otra mas elaborada construda utilizando el lenguaje de programacion
Python, denominada P Y G OBSTONES. En esta carpeta utilizaremos P Y G OBSTO -
NES ; en el apartado 9.3.3 se explica como obtenerla y como utilizarla.

Para Ampliar

Para conocer mas de Haskell, ver

www.haskell.org
Para conocer mas de Python, ver

www.python.org

Antes de estudiar la sintaxis de G OBSTONES es necesario comenzar a compren-


der este lenguaje presentando algunos de los elementos que existen en su uni-
verso de discurso, que es el conjunto de ideas que los programas G OBSTONES
describen a traves de la sintaxis del lenguaje.

2.2.1. Tablero y bolitas


El componente mas notable de G OBSTONES es el tablero. El tablero es una
cuadrcula de celdas dispuestas en filas y columnas. Cada celda es un conte-
nedor en el que puede haber bolitas de colores. En la version actual de G OBSTO -
NES existen bolitas de cuatro colores: Azul, Negro, Rojo y Verde. Las bolitas son
simples canicas como las que se usan para el juego de ninos del mismo nombre, Azul, Negro, Rojo y Verde son ex-
siendo su color la unica caracterstica importante que nos interesa observar. presiones que denotan a los colo-
res de las bolitas
En los graficos G.2.4 y G.2.5 se observan dos representaciones de un tablero
tpico, con 3 filas y 4 columnas, y algunas bolitas.

Definicion 2.2.1. El tablero es una cuadrcula de celdas. Las celdas pueden


contener bolitas de colores.

El tablero es finito, y en un principio no hay una forma directa de saber su dimen-


sion exacta. Por otra parte, las celdas tienen una capacidad ilimitada, pudiendo
contenter cualquier numero de bolitas.

2.2.2. El cabezal
Tanto el tablero como las bolitas son componentes inanimados. El factor de mo-
vimiento en G OBSTONES viene dado por una maquina que puede operar sobre
el tablero y las bolitas. Esta maquina puede realizar diversas acciones (siempre
sobre una unica celda por vez). Las acciones incluyen desplazarse a una celda
vecina, poner y sacar bolitas en la celda sobre la que se encuentra, y consultar
si hay bolitas en una celda, y cuantas hay.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


40

G.2.4. Un tablero de 3 filas y 4 columnas, en 3 dimensiones

G.2.5. El mismo tablero en 2 dimensiones

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


41

G.2.6. El tablero del grafico G.2.4 con la representacion del cabezal

G.2.7. El mismo tablero en dos dimensiones

La maquina, que sera denominada cabezal para remarcar el hecho de que opera
sobre una celda por vez, puede recibir instrucciones relativas a la celda sobre la
que se encuentra el mismo, y a la que se denomina celda actual.
En los graficos G.2.6 y G.2.7 se observa el tablero presentado antes con una
representacion del cabezal y la celda actual.

Definicion 2.2.2. El cabezal es una maquina que opera sobre una celda por vez,
la celda actual.

Para Reflexionar

Cual de los conceptos que hemos visto hasta ahora representara en el


codigo de programas G OBSTONES a las acciones que realiza el cabezal?
Y cual permitira describir los colores de las bolitas?

Otra caracterstica importante del cabezal, ademas de que puede operar sobre

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


42

una celda por vez, es que dispone de una cantidad ilimitada de bolitas de cada
color. Esto, al igual que las caractersticas del tablero y las celdas, determinara al-
gunas de las formas de hacer cosas en G OBSTONES.
Todo el objetivo de un programa G OBSTONES es servir para indicar al cabe-
zal que lleve a cabo determinada serie de modificaciones al tablero, con algun
proposito determinado. Para ello, precisamos los elementos del lenguaje.

2.2.3. Comandos simples


La manera de darle instrucciones al cabezal es a traves de un programa. Un
programa G OBSTONES se puede entender como la descripcion de las acciones
que el cabezal debe intentar realizar cuando recibe la indicacion de ejecutar el
programa, o sea, interpretar las acciones descritas all y llevarlas a cabo sobre el
tablero.
Un programa esta formado por un conjunto de definiciones, que en su parte
mas elemental estan conformadas por comandos, que, como ya mencionamos,
son descripciones de acciones individuales. Los comandos por s mismos no son
programas completos, sino que integran unidades mas grandes, denominadas
procedimientos, concepto que sera presentado en el apartado 2.2.4, y explica-
do en profundidad en la unidad 3. Todo programa contendra un procedimiento
especial, de nombre Main (idea que se describira en el subapartado 2.2.4), que
sera el que contenga los comandos que el cabezal intentara llevar a cabo al eje-
cutar dicho programa.

Definicion 2.2.3. Un programa G OBSTONES es una descripcion de las acciones


que el cabezal intentara realizar al ejecutar el mismo. Un programa G OBSTONES
Estamos empezando a aprender esta formado por definiciones de procedimientos, que a su vez estaran formados
la sintaxis especfica de un lengua- por comandos.
je de programacion!
El primer comando de G OBSTONES que vamos a presentar es el comando Poner.
Un caso particular de este comando es el comando Poner(Verde), que describe
la accion de agregar una bolita verde en la celda actual. Esta accion siempre
podra ser llevada a cabo, pues, como ya se menciono, se asume que el cabezal
Observar que el nombre < color > tiene a su disposicion una cantidad ilimitada de bolitas de cada color y, que las
se encuentra en diferente formato celdas tienen capacidad infinita, con lo cual la accion de poner siempre puede
para indicar que no debe ir la pala-
bra color, sino un color particular.
realizarse.
De aqu en mas, cuando aparezca La forma general del comando Poner esta dada por la siguiente definicion.
el nombre < color > de esta mane-
ra, querra decir que debe elegirse Definicion 2.2.4. El comando Poner(< color >) indica al cabezal que coloque
la descripcion de un color para co- una bolita del color < color > en la celda actual.
locar en ese lugar.
Los valores posibles para < color > son los ya indicados: Verde, Rojo, Azul y
Negro. O sea, son comandos validos

Poner(Verde),

Poner(Rojo),

Poner(Azul) y

Poner(Negro).

Cuando se agreguen otras formas de describir colores, tales formas tambien


podran ser usadas en donde se espera un < color >.

Definicion 2.2.5. Los valores posibles para un < color > son Verde, Rojo, Azul
o Negro.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


43

Que debe hacerse para describir la indicacion al cabezal que debe poner mas
de una bolita en la celda actual? Dicha descripcion debe contener dos comandos
seguidos. La manera de colocar seguidos comandos en G OBSTONES es ponerlos
uno a continuacion del otro; por ejemplo

Poner(Verde)
Poner(Verde)

es un fragmento de programa que describe que al ejectuarlo, el cabezal debe


colocar dos bolitas verdes en la celda actual.
Opcionalmente, pueden colocarse un punto y coma despues de un comando,
y en ese caso no es necesario colocar los comandos en lneas separadas. As,
los programas

Poner(Verde); Poner(Verde)

Poner(Verde); Poner(Verde);

tambien son validos, y equivalentes al primero.


Esta idea de poner comandos uno a continuacion del otro es una estructu-
ra de control elemental, y se conoce con el nombre de secuenciacion. La se-
cuenciacion de dos comandos es un comando compuesto que describe la accion
consistente en realizar las acciones mas simples descritas por los comandos se-
cuenciados, en el orden dado.

Definicion 2.2.6. La secuenciacion de comandos se obtiene colocando los mis-


mos uno a continuacion del otro, normalmente en lneas separadas, y opcional-
mente terminados con el caracter de punto y coma ( ;).

Otra nocion importante relacionada con los comandos es la delimitacion de un


grupo de comandos en un comando compuesto. Esto se lleva a cabo mediante
lo que se denomina un bloque, que se compone de una secuencia de comandos
delimitados por llaves. Entonces, un bloque de codigo valido sera

{
Poner(Verde); Poner(Verde)
Poner(Rojo); Poner(Rojo)
Poner(Azul); Poner(Azul)
Poner(Negro); Poner(Negro)
}

que describe una accion, cuyo efecto al ejecutarse sera colocar dos bolitas de
cada color en la celda actual. Los bloques tendran importancia en la definicion
de comandos compuestos a traves de ciertas estructuras de control.

Definicion 2.2.7. Un bloque es comando formado por un grupo de comandos


delimitados por llaves (caracteres { y }).

Un bloque tambien es un comando, con lo cual pueden secuenciarse con otros


comandos. Entonces, es valido escribir una secuencia de comandos, algunos de
los cuales sean bloques (conteniendo a su vez otras secuencias de comandos).
Por ejemplo

Poner(Verde)
Poner(Verde)
{ Poner(Rojo); Poner(Rojo) }

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


44

{
Poner(Azul); Poner(Azul)
Poner(Negro); Poner(Negro)
}

es un grupo de comandos que tendra el mismo efecto que el bloque dado previa-
mente, o sea, sera equivalente. Y dado que un bloque tambien es un comando,
Recordemos que un comando es podra a su vez ser colocado en otro bloque. Entonces, el comando
equivalente a otro cuando describe
la misma accion. {
{ Poner(Verde);Poner(Verde) }
}

es valido, y denota la accion de poner dos bolitas de color Verde. Sin embargo,
estas dos formas de usar bloques son poco comunes, reservandose el uso de
bloques para estructuras de control mas complejas.
Para Reflexionar

Cuantos comandos equivalentes puede imaginarse para describir la


accion de poner dos bolitas de cada color? Observe que hay varias ma-
neras de introducir variaciones: por asociatividad de la operacion de blo-
ques, y por anidamiento de bloques. Puede concluir que la tarea de
programar es la de encontrar la descripcion exacta a un problema, entre
una infinidad de formas diferentes? Sugerimos leer el cuento de Jorge
Luis Borges, La Biblioteca de Babel y establecer alguna analoga con
la busqueda de un programa adecuado a lo que se desea describir.

En este punto somos capaces de construir comandos cuyo unico efecto es po-
ner muchas bolitas de muchos colores. Pero todava no podemos construir un
programa. Para ello debemos presentar un par mas de conceptos.

2.2.4. Procedimientos simples


La secuenciacion de comandos induce a pensar en programas de a un comando
por vez. Esto se conoce como pensamiento operacional pues se concentra en las
operaciones individualmente. Aprender a pensar operacionalmente tiene como
consecuencia que los problemas complejos sean difciles de tratar. Es por ello
que se recomienda pensar los programas como diferentes tareas que el cabezal
debe realizar, y agrupandolas de manera conveniente. Para poder pensar con
tareas, el lenguaje debe proveernos algun mecanismo. El mecanismo utilizado
para definir tareas en G OBSTONES es el de procedimiento que no es mas que un
bloque al que se le asigna un nombre.
Para nombrar elementos del lenguaje se utiliza una forma especial de nom-
bres, llamados identificadores. Un identificador es un grupo de letras sin interrup-
ciones (o sea, no contiene espacios ni signos de puntuacion).

Definicion 2.2.8. Un identificador es un nombre conformado exclusivamente por


letras (mayusculas o minusculas), que se utiliza para denotar (o identificar o re-
ferise a) algun elemento.

La idea de identificador es mayor que la idea de palabra a la que estamos acos-


tumbrados en castellano. En la siguiente lista de ejemplos de identificadores,
pueden observarse letras, palabras y combinaciones diversas, todas las cuales
constituyen identificadores, pues son cadenas de letras sin separacion.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


45

1. x
2. sumar
3. Dibujar
4. identificadormuylargoymuyconfuso
5. UnIdentificadorMasEntendible
6. UnIdentificadorTanLargoQueNoValeLaPenaNiPensarEnEscribirlo
Los ejemplos 1, 2 y 4 comienzan con minuscula. Los ejemplos 3, 5 y 6 co-
mienzan con mayusculas. Por otra parte, los ejemplos 4 y 5 estan escritos en una
forma mixta conocida como camelCase, que es la que vamos a utilizar en esta
carpeta. Existen otras formas de escribir identificadores, y cada programador tie- De Wikipedia: CamelCase es un
ne su propio estilo. Vamos a hablar de cuestiones de estilo en el apartado 2.3. estilo de escritura que se apli-
ca a frases o palabras compues-
Actividad 3 tas. El nombre se debe a que las
mayusculas a lo largo de una pa-
labra en CamelCase se asemejan
Escribir al menos otros diez identificadores, que sirvan para describir a las jorobas de un camello. El
valores complejos y acciones cotidianas. Por ejemplo, sumarDosYTres, nombre CamelCase se podra tra-
FreirUnHuevo, etcetera. ducir como Mayusculas/Minusculas
en Camello.

Teniendo la capacidad de denotar elementos a traves de los identificadores, es-


tamos en condiciones de definir procedimientos.
es.wikipedia.org/wiki/
Definicion 2.2.9. Un procedimiento simple es un bloque con un nombre dado CamelCase
por un identificador. La definicion de un procedimiento simple tiene la forma
procedure < procName >()
< bloque >
siendo < procName > un identificador que comienza en mayuscula, y < bloque >
un bloque cualquiera. Recordar que la notacion quiere
decir que esto debe reemplazarse
Los parentesis son necesarios; su utilidad se comprendera en la unidad 3, donde por un identificador que nombre al
se definiran formas mas complejas de procedimientos. Por el momento solo se procedimiento,
procName!
y no por la palabra

veran las formas mas simples de los mismos.


Leer con Atencion

Un procedimiento simple es un bloque al que se le pone nombre.


Mas adelante veremos como ese nombre puede ser utilizado a su vez
como un comando, y entonces quedara claro la utilidad de nombrar co-
mandos complejos de esta manera.

Hay dos tipos de procedimientos: los nombrados por el programador de mane-


ra libre, y un procedimiento especial con nombre fijo. Comenzaremos por este
procedimiento especial, y luego veremos como definir procedimientos propios.

El procedimiento Main
De que manera el cabezal sabe cuales son las acciones que debe realizar an-
tes de detenerse al ejecutar un programa? En todo programa G OBSTONES existe
un procedimiento especial con nombre fijo, con el unico proposito de ser clara-
mente identificable por el cabezal. Este procedimiento debe ser el ultimo definido Significa Principal en ingles.
y su nombre debe ser Main. Es el procedimiento mas importante de un programa

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


46

G OBSTONES; para ser un programa, un conjunto de definiciones de procedimien-


tos debe contener siempre la definicion de Main, y esta debe ser la ultima de las
definiciones.
Por ejemplo, el codigo

procedure Main()
{
Poner(Verde)
Poner(Verde)
}

es un programa completo, compuesto por una unica definicion del procedimiento


Main, que a su vez esta compuesto por la secuenciacion de dos comandos Poner.
Al indicarle al cabezal que ejecute un programa, se ejecutaran todos los co-
mandos contenidos en el procedimiento Main.

Definicion 2.2.10. El procedimiento principal de un programa G OBSTONES es


un procedimiento de nombre Main, que siempre debe estar, y debe aparecer
como ultimo procedimiento. El procedimiento Main determina completamente el
comportamiento del cabezal al ejecutar el programa.

Ahora que conocemos y sabemos como definir programas completos, estamos


en condiciones de comenzar a realizar actividades de programacion.
Leer con Atencion

Las actividades de programacion incluyen dos partes: por un lado, debe


escribirse el programa en papel, para lo cual primero debe ordenar sus
ideas, nombrar los diferentes elementos y estructurar la solucion; por
otro lado, debe cargarse el programa en alguna herramienta y ejecutarlo,
para ver los resultados de manera fehaciente.

Al escribir el programa en papel, lo mas importante es validar que las ideas son
las correctas, y que estan seleccionadas y ordenadas adecuadamente para resol-
ver la tarea encomendada. Sin embargo, el codigo en papel puede considerarse
como un borrador, y puede por lo tanto contener pequenos errores, detalles que
pueden dejarse para un mejoramiento posterior porque no hacen a la estructura
de la solucion.
Leer con Atencion

Para poder ejecutar un programa G OBSTONES debe tipearlo en un ar-


chivo de texto (sin formato), e indicarle adecuadamente a la herramienta
que ejecute el programa de ese archivo. Dado que pueden existir dife-
rentes herramientas, y diferentes formas dentro de la misma herramienta
para relizar esta tarea, no daremos detalles de operacion de ninguna de
ellas como parte integral del texto. En el apartado 9.3.3 se pueden en-
contrar detalles de como obtener y utilizar una de tales herramientas.
Este tipo de errores es similar a las
faltas de ortografa y de gramatica
cometidas al escribir en castellano, Al volcar el programa escrito en papel en la computadora, sin embargo, la pre-
con la diferencia de que la maquina
no analiza nuestra intenciones co- cision es fundamental, porque si no escribimos la forma exacta, la maquina fa-
mo hara un lector humano. llara en reconocer el programa. Estos errores cometidos al escribir un programa
en la computadora se conocen como errores de sintaxis, y tienen que ver con la
rigidez que mencionamos en secciones anteriores. Por ejemplo, no es lo mismo
escribir Main que main o Mani. El primero sera reconocido adecuadamente por

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


47

la maquina, pero, por tratarse de procesos automaticos, es mucho mas complejo


que la maquina reconozca que nuestra intencion al escribir Mani fue realmente
la de escribir Main (aunque en los casos mas simples esto sea factible, en casos
mas complicados es practicamente infinita la cantidad de posibles interpretacio-
nes).
Leer con Atencion

Cada herramienta dara un mensaje de error diferente cuando encuentre


codigo que no sigue las reglas precisas de sintaxis. La interpretacion de
este mensaje de error puede resultar mas o menos compleja. La com-
prension de los errores que aparecen requiere experiencia con una he-
rramienta en particular, pues los mensajes varan drasticamente de una
a otra, e incluso de una version a otra de la misma herramienta. Uno de
los puntos mas frustrantes al aprender a programar es justamente
la interpretacion de mensajes de error. Esto sucede porque los que
programan los mensajes de error presuponen que el programador sabe
de antemano lo que el mensaje indica, aunque en realidad el estudiante
puede aun no haber aprendido los conceptos para comprenderlo.

La sugerencia general al enfrentar errores de sintaxis en una herramienta es ob-


servar en que punto del programa se informa el error, y revisar por la precision
de lo que se escribio, recordando todas las reglas vistas. Es una tarea extrema-
damente tediosa al principio, pero debe ser paciente y persistente, pues con un
poco de practica, es relativamente simple descubrir los errores mas obvios de un
vistazo. La razon por la que pusimos tanto enfasis al comienzo en la precision, y
la razon por la cual volvemos a remarcarlo aca, es justamente que la mayor cau-
sa de fracasos en los intentos de aprender a programar vienen de la diferencia
en dificultad entre escribir un programa bien en el papel y hacerlo bien en una
computadora.
Actividad de Programacion 4

Realizar el ejercicio 2.2.1. Por ser el primer ejercicio, la parte de escribir-


lo en papel ya fue realizada por nosotros. Por lo tanto, debe pasarlo en
la computadora y ejecutarlo, para lo cual debera instalar antes la herra-
mienta, como se describen en el anexo 9.3.3.

Ejercicio 2.2.1. Cargar en la herramienta, y ejecutar, el programa G OBSTONES


dado antes, que deposita dos bolitas verdes en la celda actual. Que puede
concluirse acerca del estado del tablero al iniciar la ejecucion del programa? Y
al finalizar la misma?

Recuerde escribir exactamente el codigo como fuera mostrado. Su editor de tex-


tos debera verse como en el grafico G.2.8. Si todo salio de la manera esperada,
habra obtenido un tablero final que en la celda actual tiene dos bolitas verdes
mas que el tablero inicial. Segun la herramienta que este utilizando, la forma de
visualizar este hecho puede variar. Pero en todos los casos sabemos que hay un
tablero inicial con dos bolitas verdes menos que el tablero final.
El estado del tablero es el conjunto de caractersticas que lo conforman: su
tamano, la ubicacion del cabezal y si hay o no bolitas, y en que celdas. Es impor-
tante observar que todo lo que interesa de un programa G OBSTONES es el efecto
que produce sobre el estado del tablero, o sea, los cambios que se realizaran
sobre el mismo. Es por ello importante tener idea del estado inicial del tablero.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


48

G.2.8. Texto correcto del programa G OBSTONES del ejercicio 2.2.1

Sin embargo, al escribir un programa G OBSTONES, no debera hacerse ninguna


suposicion acerca de este estado inicial. Cada herramienta es libre de usar como
estado inicial uno cualquiera, e incluso podra ser que el estado inicial variase de
una ejecucion a otra.

Definicion 2.2.11. El efecto de un programa G OBSTONES es el conjunto de cam-


bios que produce sobre el tablero inicial. No debe suponerse ningun estado inicial
particular si se desea que el programa sea independiente de la herramienta.

Antes de pasar a realizar ejercicios donde usted escriba sus propios programas
para solucionar tareas sencillas, veremos un ejercicio mas, con el fin de trabajar
sobre la nocion de error.
Actividad de Programacion 5

Realice el ejercicio 2.2.2. Recuerde ser paciente y persistente con los


mensajes de error, incluso aunque al principio la tarea pueda resultar
algo frustrante.

Ejercicio 2.2.2. Escribir el siguiente programa G OBSTONES y ejecutarlo.

prosedure main()
{ poner(Roja) }

Observar el mensaje de error que se produce, y corregir los errores hasta que el
programa resulte ejecutable.

Recuerde que al escribirlo en la herramienta, el programa debe aparecer exac-


tamente como lo escribimos. El editor de texto debera verse como en el grafi-
co G.2.9.
El informe de los errores en la herramienta P Y G OBSTONES es razonablemen-
te adecuado para un novato. Sin embargo, no hay que confiar en que la herra-
mienta detecte siempre nuestras intenciones. Los errores aparecen siempre en
los programas, ya sea por descuidos, suposiciones incorrectas, o conocimientos
insuficientes, y la unica manera de encontrarlos y eliminarlos es aprender a inter-
pretar mensajes de error. En todos los ejercicios posteriores no nos sera posible
mostrarle la forma exacta en la que debe verse el editor, pues habra cientos de
opciones correctas y cientos de miles de opciones incorrectas! Por eso es tan
importante que aprenda a manejar sus errores.
Ahora s, podemos realizar el primer ejercicio completo de programacion.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


49

G.2.9. Texto correcto del programa G OBSTONES del ejercicio 2.2.2, al comenzar
el ejercicio

Actividad de Programacion 6

Realizar el ejercicio 2.2.3. Recuerde que para poder realizarlo, debe pri-
mero escribirlo en papel, y luego pasarlo en la computadora y ejecutarlo.

Ejercicio 2.2.3. Escribir un programa G OBSTONES que deposite una bolita ver-
de, dos rojas, tres azules y cuatro negras en la celda actual, y ejecutarlo.

Cuando ya se adquiere cierta practica, la etapa de escribir en papel suele omitirse


para los programas mas simples. Sin embargo, incluso los programadores mas
experimentados tomamos una hoja de papel para empezar a organizar nuestras
ideas antes de usar la computadora.
Para Reflexionar

Revise todo lo ledo hasta el momento, e intente identificar cuales son las
actividades importantes al pensar sobre el papel, y cuales al escribir el
codigo en la computadora para ejecutarlo. Relacione esto con la defini-
cion de programa dada, y observe que cosas tienen que ver con la parte
de los programas en cuanto descripciones y que cosas con la parte en
cuanto descripciones ejecutables. La tarea del programador comienza
por pensar lo que quiere describir, y luego darle forma ejecutable. . .

Procedimientos definidos por el programador

Otros procedimientos simples son aquellos que puede nombrar el programador


libremente. La forma es la misma que la del procedimiento Main, salvo que el
programador puede elegir cualquier nombre (dado por un identificador, o sea,
que sea solo formado por letras y que comience con mayusculas), y que debe
colocar sus definiciones antes que las de Main. Por ejemplo, un procedimiento
definido (o declarado) por el programador podra ser

procedure PonerDosVerdes()
{
Poner(Verde); Poner(Verde)
}

La forma general es la que se definio al principio del apartado.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


50

Es importante observar que un procedimiento definido por el programador por


s solo NO constituye un programa. La diferencia entre un procedimiento definido
por el programador y el procedimiento Main es que mientras este ultimo es invo-
cado de manera implcita al ejecutar el programa, un procedimiento definido por
el programador debe ser invocado de manera explcita por el codigo de Main para
que el mismo sea considerado por la maquina. Para ello, el nombre de un pro-
cedimiento declarado seguido de parentesis se puede utilizar como un comando.
Entonces

procedure PonerDosVerdes()
{
Poner(Verde); Poner(Verde)
}
procedure Main()
{
PonerDosVerdes(); PonerDosVerdes()
}

es un programa G OBSTONES que coloca cuatro bolitas verdes en la celda actual.

Definicion 2.2.12. Un procedimiento declarado por usuario puede ser utilizado


como comando. Se escribe el nombre seguido por parentesis, de la siguiente
forma

< procName >()

El efecto de dicho comando es el mismo que el del bloque definido en la decla-


racion del procedimiento del mismo nombre.

Observar como ahora la tarea de poner dos bolitas verdes ya no queda expre-
sada unicamente por una secuenciacion, sino que a traves del uso de proce-
dimientos hemos podido darle un nombre significativo a esa tarea. Cada vez
que precisemos poner dos bolitas verdes podemos recurrir al nuevo comando
Para que sea realmente un nue- PonerDosVerdes().
vo comando, su definicion debe en-
contrarse entre las definiciones de Leer con Atencion
procedimientos del programa.
Podramos decir que las tareas son situaciones complejas a resolver, y
los procedimientos, la forma de describir tareas (de la misma forma que
las acciones son la manera de producir efectos, y los comandos, la forma
de describir acciones).

Esta habilidad es fundamental para poder encarar tareas complejas. Uno de los
errores mas tradicionales en los cursos basicos de programacion consiste en
mantener el pensamiento operacional demasiado tiempo, pues resulta mas sen-
cillo pensar los primeros ejemplos de manera operacional. Sin embargo, esto
complica y dificulta luego el aprendizaje posterior. Pero antes de trabajar sobre
esta manera de pensar con tareas y procedimientos, vamos a enriquecer el re-
pertorio de comandos basicos.

2.2.5. Mas comandos simples


Que otras ordenes elementales se le pueden dar al cabezal? As como existe
una forma de describir la accion del cabezal de poner una bolita en la celda
actual, existe la accion opuesta, de sacarla. El comando Sacar(Verde) saca una
bolita verde de la celda actual, si hay alguna.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


51

La forma general del comando Sacar es similar a la de Poner, y esta dada por
la siguiente definicion.
Definicion 2.2.13. El comando Sacar(< color >) indica al cabezal que quite una
bolita del color < color > de la celda actual, si hay alguna.
No olvidar que esto siginifica un co-
Debe observarse que el cabezal solo puede realizar una accion de Sacar si se lor en particular, y no la palabra
cumplen ciertos requisitos. Dado que el cabezal no es mas que una maquina, y color. . .
bastante limitada, no tiene ninguna manera de saber que hacer cuando la des-
cripcion para la accion a realizar no incluya alguna situacion. Si bien las personas,
antes tal situacion, podemos tomar decisiones, las computadoras no pueden.
Cuando el cabezal recibe una orden que no puede ejecutar, toma una accion
drastica: se autodestruye, y con el al tablero y todas las bolitas. Esto puede pa-
recer exagerado para una persona, que siempre tiene otros cursos de accion para
considerar, pero no lo es para una maquina, al menos no para una tan simple.
Cuando un comando describe una accion que puede provocar la autodestruccion
del cabezal en caso de que ciertos requisitos no se cumplan, se dice que tal co-
mando describe una operacion parcial, pues solo describe parcialmente la accion
a realizar. Si en cambio la descripcion conlleva una accion que siempre puede
realizarse, se dice que es una operacion total. Al requisito que debe cumplirse
antes de intentar ejecutar una operacion parcial para estar seguro que la misma
no falla se la denomina precondicion de la operacion. De esta manera, Poner es
una operacion total, y Sacar es una operacion parcial y su precondicion es que
haya una bolita del color indicado en la celda actual.
Definicion 2.2.14. Una operacion total es la descripcion de una accion que, al
no tener requisitos para que el cabezal pueda llevarla a cabo, siempre puede ser
realizada.
Definicion 2.2.15. Una operacion parcial es la descripcion de una accion que
precisa que ciertos requisitos se cumplan para que el cabezal pueda llevarla a
cabo, y que en caso de que los mismos no se cumplan, provoca la autodestruc-
cion del cabezal y todos los elementos.
Definicion 2.2.16. La precondicion de una operacion parcial expresa los requi-
sitos que deben cumplirse para que la ejecucion de la accion indicada por la
operacion pueda ser llevada a cabo sin provocar la autodestruccion del cabezal.
De aqu en mas, al presentar nuevos comandos, se establecera si los mismos
describen operaciones totales o parciales, y en caso de que sean parciales,
cuales son sus precondiciones. En el caso de operaciones parciales, normalmen-
te se indicara solamente la accion descrita por el comando en el caso en que la
precondicion sea verdadera. Por ejemplo, diremos que Sacar saca una bolita de
la celda actual; si la bolita no existiese, la precondicion sera falsa y por lo tanto tal Recordar que los comandos des-
situacion no se indica. En algunos casos, podremos hacer la salvedad aclarando criben acciones y no que hacen
acciones. Tener en cuenta este
la precondicion en la accion: Sacar saca una bolita de la celda actual, si existe. abuso del lenguaje al leer el resto
Actividad de Programacion 7 del cuadernillo.

Realizar los ejercicios 2.2.4 y 2.2.5. Observe que si en el estado inicial


del tablero ya haba bolitas, el programa del ejercicio 2.2.4 no fallara.
Pruebe con un tablero que no tenga bolitas en la celda actual.

Ejercicio 2.2.4. Escribir un programa Gobstones que saque una bolita de la cel-
da actual sin que haya ninguna, y comprobar la forma en que se manifiesta la
autodestruccion del cabezal, el tablero y los otros elementos.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


52

Ejercicio 2.2.5. Escribir un programa Gobstones que saque una bolita de la cel-
da actual, pero que no produzca la autodestruccion del cabezal. Como se puede
asegurar que la precondicion del comando Sacar se cumpla? Piense solo en los
elementos presentados hasta el momento. . .

Toda vez que se utiliza una operacion parcial, hay que tomar una de dos medidas:
o bien se busca garantizar la precondicion de la misma de alguna manera (como
en el ejercicio 2.2.5) o bien se trasladan los requerimientos de dicha operacion a
la operacion que se esta definiendo. Veremos esto con cuidado mas adelante.
Para Reflexionar

Los errores en los programas de computadora son algo que sufrimos


cotidianamente. Basta pensar en las veces que escuchamos se cayo el
sistema. Es responsabilidad de los programadores programar de mane-
ra que la cantidad de errores sea mnima. Las precondiciones son uno de
los mecanismos mas utiles para lograr esto. Reflexionar sobre la impor-
tancia de aprender a programar de manera adecuada, y sobre lo simple
que resulta programar sin tener estas cosas en cuenta. Relacionarlo con
el estado de situacion de los programas que conoce.

Otro comando que describe una operacion parcial es el que permite al cabezal
moverse por el tablero. Esta operacion es basica para poder operar en mas de
una celda. El comando Mover(Norte) describe la accion de que el cabezal se
debe desplazar una celda hacia el norte, si hay alguna celda en esa direccion. El
formato general esta dado por esta definicion
Definicion 2.2.17. El comando Mover(< dir >) indica al cabezal que debe mo-
verse una celda en la direccion < dir >, si es posible.
Las direcciones posibles (los valores que puede tomar < dir >) son Norte, Sur,
Este y Oeste.
Definicion 2.2.18. Los valores posibles para una direccion son Norte, Sur, Este
y Oeste.

Como se menciono, Mover es una operacion parcial. Su parcialidad esta dada


por el hecho de que el tablero es finito, y por lo tanto hay celdas que no tienen
celda vecina en algunas direcciones. Por ejemplo, la celda de la esquina inferior
izquierda del tablero no tiene celdas ni al Sur ni al Oeste, y es la unica celda
con esta caracterstica. Observar que dado que el tamano del tablero no se co-
noce a priori, puede ser que un programa que no controle adecuadamente sus
movimientos provoque la autodestruccion del cabezal. Por ejemplo, el programa
procedure Main()
{ Mover(Sur);Mover(Oeste) }
tiene como precondicion comenzar su ejecucion en cualquier celda que no se
encuentre en la fila de mas al sur, ni en la columna de mas al oeste. En caso
que la ejecucion del programa arranque en una de dichas celdas, provocara la
autodestruccion del cabezal.
Puesto que la posicion inicial del cabezal es desconocida, es util contar con el
comando IrAlOrigen. Este comando, cuya forma es simplemente IrAlOrigen(),
describe una operacion total cuyo efecto es posicionar el cabezal en la esquina
inferior izquierda del tablero. Posteriormente, en la unidad 4 se veran las he-
rramientas necesarias para que este comando pueda ser reemplazado por un
procedimento equivalente definido por el programador.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


53

Comando Precondicion Accion descrita

Poner(< color >) Ninguna Pone una bolita del color indica-
(operacion total) do en la celda actual
Que exista una boli-
Sacar(< color >) Saca una bolita del color indica-
ta del color indicado
do de la celda actual
en la celda actual
Que exista una cel- Mueve el cabezal una celda en
Mover(< dir >) da en la direccion la direccion indicada respecto
indicada de la celda actual

IrAlOrigen() Ninguna Mueve el cabezal a la celda infe-


(operacion total) rior izquierda del tablero

VaciarTablero() Ninguna Elimina todas las bolitas del


(operacion total) tablero

T.2.1. Sumario de los comandos basicos conocidos hasta el momento

Asimismo, y puesto que el contenido de las celdas es arbitrario al iniciar, es


util contar con el comando VaciarTablero. Este comando, cuya forma es simple-
mente VaciarTablero(), describe una operacion total cuyo efecto es eliminar la
totalidad de las bolitas del tablero, sin alterar la posicion del cabezal. Al igual que
el comando IrAlOrigen, el comando VaciarTablero puede ser reemplazado por
un procedimiento definido por el programador, aunque para ello se requiere co-
nocer casi la totalidad de elementos que posee el lenguaje.
En este punto, es bueno hacer un pequeno repaso de los comandos vis-
tos hasta el momento, y sus caractersticas. Esto se puede encontrar en la ta-
bla T.2.1. Estos comandos pueden ser combinados mediante secuenciacion, agru-
pados en bloques, y usados en definiciones de procedimientos que determinaran
nuevos comandos, definidos por el programador.
Es el momento de comenzar a escribir programas interesantes.

2.2.6. Utilizando adecuadamente procedimientos

Combinando las operaciones de Mover y Poner se pueden simular dibujos utili-


zando las bolitas como colores. Por ejemplo, diremos que el programa

procedure Main()
{
Mover(Norte); Poner(Negro)
Mover(Este); Poner(Negro)
Mover(Sur); Poner(Negro)
Mover(Oeste); Poner(Negro) Recordar que en realidad sera co-
} rrecto decir que el programa descri-
be la tarea de dibujar un cuadrado
negro.

dibuja un pequeno cuadrado negro de dos celdas de lado.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


54

Actividad de Programacion 8

Realizar el ejercicio 2.2.6. Probarlo varias veces, con el cabezal en distin-


tas posiciones, y comprobar que este programa describe una operacion
parcial.

Ejercicio 2.2.6. Ejecutar el programa Gobstones dado antes, y comprobar que


dibuja el cuadrado. Cual es la precondicion de este programa?

Leer con Atencion

Si bien G OBSTONES no es un lenguaje para expresar dibujos, y el tablero


no es un papel o una pantalla, podemos interpretar el problema de dibu-
jar un cuadrado en terminos del tablero y bolitas. Esta interpretacion es
una de las maneras fundamentales de representar cosas en los lengua-
jes de programacion: se utilizan ciertos elementos, pero se entienden
como si se tratase de otros elementos.

Entonces, a traves de algunos dibujos bien coordinados podemos ver ventanas,


botones y otros elementos abstractos en una pantalla de computadora, aunque
Para los que conocen la pelcula solo se trate de puntitos de luz que los programadores podemos controlar. Al
Matrix, en programacion solemos enunciar ejercicios haremos uso intuitivo de esta forma de interpretacion. En el
decir que debemos tratar de enten-
der la verdad. . . la cuchara no exis-
apartado 2.3 profundizaremos un poco la idea de representar informacion en
te. . . y ese es el primer paso para terminos de los elementos presentes en el universo de discurso de un lenguaje.
poder doblarla. Es conveniente, como ya se menciono, que se utilicen procedimientos para
nombrar adecuadamente las tareas, pues al escribir programas para solucionar
tareas mas complejas, se vuelve imposible determinar adecuadamente la correc-
cion del programa si se razona de manera operacional. Esta forma de pensar un
programa solo sirve con los programas mas simples. Pensar por tareas permite
generalizar adecuadamente el programa. Por esta razon, el programa anterior
podra haberse escrito usando procedimientos como
Prestar atencion a los identificado-
procedure DibujarLineaHaciaElNorte()
res elegidos para nombrar los pro-
cedimientos. Discutiremos acerca { Mover(Norte); Poner(Negro) }
de esto en el apartado 2.3. procedure DibujarLineaHaciaElEste()
{ Mover(Este); Poner(Negro) }
procedure DibujarLineaHaciaElSur()
{ Mover(Sur); Poner(Negro) }
procedure DibujarLineaHaciaElOeste()
{ Mover(Oeste); Poner(Negro) }
procedure DibujarCuadradoNegro()
{
DibujarLineaHaciaElNorte()
DibujarLineaHaciaElEste()
DibujarLineaHaciaElSur()
DibujarLineaHaciaElOeste()
}
procedure Main()
{ DibujarCuadradoNegro() }
Observar que el programa es mas extenso de esta forma que la anterior. Sin
embargo, ahora estamos en condiciones de generalizarlo de varias maneras.
Por ejemplo, cambiando solamente los procedimientos que dibujan lneas de la
siguiente manera

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


55

procedure DibujarLineaHaciaElNorte()
{
Mover(Norte); Poner(Negro)
Mover(Norte); Poner(Negro)
}
procedure DibujarLineaHaciaElEste()
{
Mover(Este); Poner(Negro)
Mover(Este); Poner(Negro)
}
procedure DibujarLineaHaciaElSur()
{
Mover(Sur); Poner(Negro)
Mover(Sur); Poner(Negro)
}
procedure DibujarLineaHaciaElOeste()
{
Mover(Oeste); Poner(Negro)
Mover(Oeste); Poner(Negro)
}

y dejando los restantes procedimientos sin alteraciones, podramos hacer un pro-


grama para dibujar un cuadrado de tamano mas grande.
Entendemos que se trata de dibujar
Actividad de Programacion 9 solo los lados del cuadrado. O sea,
no se trata de un cuadrado solido.
Cargar en la herramienta los dos programas anteriores (los que realizan
cuadrados de lado 2 y 3 usando procedimientos) y ejecutarlos. Obser-
var que los dos definen operaciones parciales. Observar ademas que
el primero de los programas es equivalente al del ejercicio 2.2.6, pero
es mas facil de entender. Realizar el ejercicio 2.2.7 teniendo en cuen-
ta estas cuestiones. Quizas encuentre util invocar a los procedimientos
IrAlOrigen() y VaciarTablero() antes de invocar al de dibujar, para
lograr que la precondicion del programa se cumpla mas seguido.

Ejercicio 2.2.7. Escribir dos programas Gobstones equivalentes que dibujen un


cuadrado de cuatro celdas de lado, uno de ellos utilizando exclusivamente un
unico procedimiento Main, y el otro utilizando adecuadamente procedimientos
definidos por el programador. Cual es la precondicion de los programas?

Para Reflexionar

Observe detenidamente los dos programas escritos en el ejercicio 2.2.7


y establezca la dificultad de comprender o modificar cada uno de ellos.
Reflexione sobre la utilidad de los procedimientos, y como estos son ab-
solutamente necesarios una vez que se encaran tareas mnimamente no
triviales. Reflexione sobre los cambios necesarios en los procedimientos
para realizar una tarea diferente y en como es sencillo determinar en
que lugares realizar los cambios si los procedimientos fueron definidos
y nombrados adecuadamente.

Esta forma de dividir un programa en tareas y definir un procedimiento para cada


una de ellas hace que el foco de atencion en programacion sea puesto en los

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


56

procedimientos individuales. De esta forma, en lugar de pedir un programa que


haga cierta tarea, se pedira la definicion de un procedimiento particular que reali-
ce la tarea. Por ejemplo, el ejercicio de dibujar un cuadrado se podra enunciar
de la siguiente manera:

Ejercicio 2.2.8 (reformulacion del ejercicio 2.2.7).


Escribir un procedimiento DibujarCuadrado que dibuje un cuadrado Negro de
tres celdas de lado.

Leer con Atencion

Al enunciar un problema se asume que el requerimiento de escribir el


programa Main es implcito, o sea, debe crearse un procedimiento Main
que invoque al procedimiento solicitado en el enunciado, aunque tal cosa
no este pedida de manera explcita en el.

Ademas, muchas veces seran necesarios varios procedimientos diferentes com-


binados adecuadamente para llevar a cabo una tarea. En ese caso, se presen-
tara y discutira cada uno de ellos por separado, dejando su combinacion implcita.
Asimismo, se asumira que los ejercicios previos han sido realizados, y pueden por
lo tanto reutilizarse. Como ejemplo de esto, consideremos el siguiente enunciado.

Ejercicio 2.2.9. Escribir un procedimiento llamado CuadradoNegroARojo que su-


poniendo que hay un cuadrado Negro de lado tres a partir de la celda actual, lo
transforme en un cuadrado Rojo. Cual es la precondicion de este procedimien-
to?

La solucion para este problema sera dada de la siguiente manera

procedure TrasformarLineaHaciaElNorte()
{
Mover(Norte); Sacar(Negro); Poner(Rojo)
Mover(Norte); Sacar(Negro); Poner(Rojo)
}
procedure TrasformarLineaHaciaElEste()
{
Mover(Este); Sacar(Negro); Poner(Rojo)
Mover(Este); Sacar(Negro); Poner(Rojo)
}
procedure TrasformarLineaHaciaElSur()
{
Mover(Sur); Sacar(Negro); Poner(Rojo)
Mover(Sur); Sacar(Negro); Poner(Rojo)
}
procedure TrasformarLineaHaciaElOeste()
{
Mover(Oeste); Sacar(Negro); Poner(Rojo)
Mover(Oeste); Sacar(Negro); Poner(Rojo)
}
procedure CuadradoNegroARojo()
{
TrasformarLineaHaciaElNorte()
TrasformarLineaHaciaElEste()
TrasformarLineaHaciaElSur()

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


57

TrasformarLineaHaciaElOeste()
}
El primer detalle a observar es que si bien el procedimiento solicitado es sola-
mente CuadradoNegroARojo, la solucion involucra la definicion de cinco procedi-
mientos diferentes. Esto no es parte del requerimiento original explcito, pero una
buena practica de programacion se consigue eligiendo convenientemente las ta-
reas a describir, y nombrandolas adecuadamente (volveremos sobre este punto
en el apartado 2.3).
Otro detalle a observar tiene que ver con como probar este procedimiento.
Puesto que la precondicion de CuadradoNegroARojo es que exista un cuadrado
negro de lado tres ya dibujado en el tablero, no tendra sentido utilizar como
programa Main
procedure Main()
{
VaciarTablero()
IrAlOrigen()
CuadradoNegroARojo()
}
pues este programa siempre fallara. Se requiere, en cambio, asegurar primero la
precondicion de CuadradoNegroARojo, utilizando alguna otra forma. Una de ellas,
por ejemplo, es utilizar algun otro procedimiento para preparar el tablero antes de
llamar al procedimiento a probar, como en
procedure Main()
{
VaciarTablero()
IrAlOrigen()
DibujarCuadradoNegro()
CuadradoNegroARojo()
}
Otra de las formas, si la herramienta lo permite, es tener un tablero predefinido
donde el cuadrado negro ya ha sido dibujado a partir del origen, y entonces usar
como procedimiento principal simplemente
procedure Main()
{
IrAlOrigen()
CuadradoNegroARojo()
}
Pero como esto es dependiente de cada herramienta, no nos extenderemos en
estas alternativas. Sera tarea del estudiante buscar la forma de probar los proce-
dimientos que se solicitan en las actividades de programacion.
Actividad de Programacion 10

Realice el ejercicio 2.2.10. Observe que para que el mismo funcione su


programa debe contener 10 definiciones de procedimientos ademas del
Main (y no solo los 5 correspondientes al ejercicio 2.2.9).

Ejercicio 2.2.10. Escribir un programa G OBSTONES que utilice CuadradoNegroARojo,


y que, si el tablero es lo suficientemente grande, no falle.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


58

Observar que en el ejercicio 2.2.10 no se indica como debe conseguirse que


al invocar el procedimiento CuadradoNegroARojo se cumpla su precondicion. La
precondicion de un procedimiento solicitado debe satisfacerse de alguna manera
para poder probarlo. O sea, el ejercicio 2.2.9 implicara que debe hacerse tambien
el ejercicio 2.2.10, aunque esto no se indicara de ninguna manera a partir de
ahora. Observar que tambien esta implcita la necesidad de comprobar que el
programa funciona, ejecutandolo.
Habra comprobado que ya esta escribiendo programas complejos! Antes de
proseguir con los conceptos estructurales, vamos a hablar de algunas cuestiones
de estilo que afectan la manera en que las personas leemos los programas.

2.3. Acerca de las cuestiones de estilo


Hasta ahora vimos que al aprender un lenguaje de programacion, existen nu-
merosas reglas rgidas que debemos aprender para poder escribir programas.
Sin embargo, tambien aparecieron ciertas cuestiones de estilo, que si bien no
remarcamos demasiado, son parte importante de la forma en que escribimos
programas.
Puesto que un programa G OBSTONES es una descripcion de la solucion a un
problema, cabe hacer la pregunta de quien leera esta descripcion. La respuesta
basica es que el programa debe ser ledo por el cabezal para realizar las accio-
nes. Pero otro punto importante es que el programador tambien debe leerlo, para
realizar cambios, mejoras, descubrir posibles errores, etcetera.
Las reglas rgidas, como ya vimos, tienen que ver con los programas en cuan-
to a piezas ejecutables, o sea, con las maquinas que deben leer y analizar los
programas, que son limitadas y esperan las cosas de cierta manera fija. Las cues-
tiones de estilo, en cambio, tienen que ver con los programas en cuanto descrip-
ciones, con las personas que deben leer y comprender el codigo. Un buen estilo
resulta en codigo con mayor legibilidad, esto es, hace al programa mas sencillo
La legibilidad es una propiedad del de leer y comprender por las personas que lo lean.
codigo que muestra el grado de Como con toda cuestion de estilo, no hay reglas fijas, universales, que esta-
simplicidad con el que una persona
que lee el codigo puede entenderlo. blezcan que es correcto y que es incorrecto, o que es comodo o incomodo hacer.
Cada programador posee un gusto diferente con respecto a las cuestiones de
estilo. Sin embargo, hay algunos extremos que son claramente entendibles o cla-
ramente inentendibles, y por lo tanto sencillos de identificar. Entonces, la tarea
del programador a medida que adquiere experiencia, es identificar estas cuestio-
nes de estilo, evitar practicas que conduzcan a codigos ilegibles, y en el camino,
incorporar su propio estilo.
Por supuesto, adquirir un estilo propio no es tarea sencilla, y el consejo al co-
menzar es copiar el estilo de otros. Copiando de la suficiente cantidad de progra-
Esto es similar a lo que ocurre madores, pueden identificarse muchas de las practicas consideradas correctas o
cuando uno aprende a bailar un incorrectas en estilo. En este cuadernillo hemos utilizado un estilo especfico, y
baile especfico, como tango o sal-
sa, o cuando aprende a dibujar o
esperamos que los estudiantes lo imiten, al menos mientras adquieren el propio.
pintar Para que esto no sea algo totalmente impensado y automatico, en este apartado
vamos a presentar algunas de las cuestiones de estilo mas importantes, y los
principios por los que nos guiamos en este cuadernillo.

2.3.1. Indentacion de codigo


La primera cuestion de estilo esta relacionada con la forma en la que el codigo
es visualizado. Como hemos visto, el codigo no se muestra como algo completa-
mente lineal, sino mas bien bidimensional: usamos ciertos elementos debajo de

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


59

otros para indicar que los primeros estan subordinados a los segundos. Por ejem-
plo, al bloque nombrado por la definicion de un procedimiento simple lo hemos
puesto hasta ahora siempre debajo de la lnea que indica que se esta definiendo
el mismo.
Desde el punto de vista de la herramienta que ejecuta los programas, es lo
mismo un caracter de espaciado que quinientos, ya que lo que importa es po-
der distinguir que hay mas de un elemento uno a continuacion del otro, y no a
que distancia estan. Los caracteres de espaciado estan dados por los espacios
en blanco, los fines de lnea y los tabuladores. Entonces, son equivalentes el
codigo

procedure PintarCelda()
{
Poner(Rojo)
Poner(Rojo)
}

y el codigo

procedure PintarCelda() { Poner(Rojo); Poner(Rojo) }

y tambien el codigo

procedure
PintarCelda()

{
Poner(Rojo)

Poner(Rojo)

Lo repetimos: estas tres variaciones del codigo son equivalentes. Recordemos


que esto quiere decir que tendran exactamente el mismo efecto. Entonces, por
que molestarse con cual de las 3 elegir? Claramente, la tercera de las formas
es casi inentendible para un lector humano, a pesar de que la computadora las
considerara exactamente igual. La diferencia entre la primera y la segunda, en
cambio, es mas sutil.
Actividad de Programacion 11

Pruebe las variaciones anteriores en la herramienta, y verifique que las


tres formas son equivalentes. Encuentre otras variaciones posibles que
resulten en codigo equivalente (aunque sea ilegible o innecesariamente
complicado).

A la forma exacta en que el codigo es mostrado en dos dimensiones, en funcion Indent tambien significa dejar mar-
de variar el numero de caracteres de espacio que se utilizan, se lo denomina cas en una superficie, ademas de
indentar el codigo. El termino indentar es un neologismo basado en el termino sangrar.
ingles indent, que significa sangrar, como en el castellano sangra. Entonces, in-
dentar un codigo es sangrarlo, o sea, comenzar ciertas lneas mas adentro que
otras, como se hace en el primer parrafo de los textos en castellano; en otros

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


60

terminos, es agregarle sangras al texto del codigo. Dado que el termino caste-
llano sangrar es sinonimo tambien de, y mas comunmente reconocido como, per-
der sangre, muchos programadores de habla castellana (pero no los espanoles)
Los espanoles son extremadamen- preferimos usar el termino indentar.
te recelosos de los neologismos
o anglicismos, y traducen todo de Para Ampliar
manera literal. Esto resulta confu-
so, pues hablan de sangrado de
codigo, lo cual a nosotros nos hace Buscar en la web discusiones sobre indentacion (o sangrado)
pensar en codigo al que se le saca de codigo. El primer sitio que sale en Google es la Wikipedia:
sangre. . .

http://es.wikipedia.org/wiki/Indentacion
que dice
Indentacion es un anglicismo (de la palabra inglesa indentation)
de uso comun en informatica que significa mover un bloque de
texto hacia la derecha insertando espacios o tabuladores para
separarlo del texto adyacente, lo que en el ambito de la impren-
ta se ha denominado siempre como sangrado o sangra. En los
lenguajes de programacion de computadoras la indentacion es
un tipo de notacion secundaria utilizado para mejorar la legi-
bilidad del codigo fuente por parte de los programadores, te-
niendo en cuenta que los compiladores o interpretes raramente
consideran los espacios en blanco entre las sentencias de un
programa. Sin embargo, en ciertos lenguajes de programacion
como Haskell, Occaml y Python, la indentacion se utiliza pa-
ra delimitar la estructura del programa permitiendo establecer
bloques de codigo. Son frecuentes discusiones entre progra-
madores sobre como o donde usar la indentacion, si es mejor
usar espacios en blanco o tabuladores, ya que cada programa-
dor tiene su propio estilo.

Definicion 2.3.1. Indentar codigo es seleccionar la forma en que el mismo se


muestra en dos dimensiones, en funcion de variar el numero de caracteres de
espacio que se utilizan.

Leer con Atencion

Entonces, realizamos nuevamente la pregunta: por que puede resultar


mejor indentar el codigo de cierta manera? La indentacion de codigo
realza la comprension de la estructura del texto, o sea, que elementos
estan subordinados a que elementos, y que informacion es valida en
que contexto. Por ello, una adecuada indentacion es fundamental.

Como con todas las cuestiones de estilo, la percepcion sobre lo que es adecua-
do y lo que no vara con las personas, e incluso con el contexto. Algunas formas
son claramente incorrectas (como la tercer variante que vimos antes), pero otras
son solo cuestion de costumbre. Por ejemplo, en este cuadernillo hemos elegido
colocar el bloque nombrado por un procedimiento en una lnea independiente al
encabezado de su declaracion, y en el caso que el bloque ocupe mas de una
lnea, con las llaves en sus propias lneas, y uno o dos caracteres mas adentro
que la palabra procedure; los comandos del bloque van entre medio de ambas

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


61

llaves, otros dos caracteres mas adentro. El resultado, que ya hemos visto nume-
rosas veces, es el siguiente

procedure DibujarLinea()
{
Poner(Negro); Mover(Norte)
Poner(Negro); Mover(Norte)
}

Sin embargo, otros estilos son posibles. El mismo codigo, indentado por un pro-
gramador de la comunidad Java, habra sido
Java es uno de los principa-
procedure DibujarLinea() { les lenguajes de programacion de
Poner(Negro); Mover(Norte) hoy da. Para conocer mas so-
Poner(Negro); Mover(Norte) bre el lenguaje Java, ver el sitio
}

Observe como la llave de apertura se coloca en la misma lnea que el encabeza- www.java.com/es
do, y la correspondiente de cierre a la misma altura que la palabra procedure.
Otra variacion de estilo, que usaremos en ocasiones, consiste en que, cuando
el codigo del procedimiento es breve, se muestra en una unica lnea, como en

procedure DibujarLineaCorta() { Poner(Negro); Mover(Norte) }

o a veces

procedure DibujarLineaCorta()
{ Poner(Negro); Mover(Norte) }

Al principio intente imitar el estilo de indentacion utilizado en este cuadernillo,


pero a medida que avance en la escritura de sus propios programas, experimente
con otras variaciones para ver cual le resulta mas comoda. Recuerde que la
forma en que otros programadores leen el codigo tambien se vera afectada por
sus cambios. Y tambien que una de las cuestiones que se evaluan al corregir
codigo de los estudiantes es la comprension sobre la estructura del mismo! Eso
es lo que debe reflejar en la indentacion.

2.3.2. Eleccion de nombres adecuados de identificadores


La segunda cuestion fundamental de estilo tiene que ver con la eleccion de nom-
bres para los identificadores. A este respecto, hay dos aspectos basicos:

1. que nombres elegir para describir adecuadamente la solucion;

2. que forma de escribir nombres complejos se utiliza.

El aspecto de como escribir nombres complejos tiene varias opciones mas o me-
nos estandarizadas en la comunidad de programadores. Por ejemplo, en este
cuadernillo hemos elegido usar CamelCase, que como vimos, es un estilo de es-
critura para identificadores compuestos de varias palabras, y donde cada palabra
se escribe con mayusculas.
Otro estilo muy difundido es utilizar guiones bajos (underscores en ingles)
para separar las palabras, en lugar de poner en mayusculas cada una de las
letras. Comparemos, por ejemplo,

UnIdentificadorEnCamelCase con

un identificador NO en camel case.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


62

Cada comunidad de programacion tiene su propia preferencia por uno u otro


estilo, o por algunas variaciones, e incluso en algunos casos por estilos comple-
tamente distintos. Lo que es claro es que se trata de una cuestion puramente es-
tilstica, y que, por lo tanto, genera discusiones fundamentalistas, cuasi-religiosas
(o para decirlo de otra manera mas elegante, semi-cientficas).
Para Ampliar

Para ampliar sobre el tema de las discusiones semi-cientficas al respec-


to de cual estilo es mejor, ver, por ejemplo
Recurso Web

http://whathecode.wordpress.com/2011/02/10/
camelcase-vs-underscores-scientific-showdown/

Pero no olvide que en este cuadernillo favorecemos el CamelCase!

Ahora bien, el otro aspecto, referente a los nombres de identificadores, es crucial,


y es por ello la que mas debates fundamentalistas genera en los programadores.
En este aspecto, se trata de que nombres elegir para describir una tarea y as te-
ner procedimientos bien nombrados.
Debemos tener en cuenta que el nombre exacto de un procedimiento no es
importante para la herramienta, pues al ejecutar, se limita a buscar la definicion
de un procedimiento con ese nombre. Entonces, para la herramienta, y puesto
que los tres generan el mismo efecto, son equivalentes el programa
procedure PonerGotaAcuarelaRoja() { Poner(Rojo) }
procedure Main { PonerGotaAcuarelaRoja() }
con el programa
procedure ColocarAlienigena() { Poner(Rojo) }
procedure Main { ColocarAlienigena() }
y con el programa
procedure A() { Poner(Rojo) }
procedure Main { A() }
Sin embargo, para un lector humano, el primero da cuenta de que el programador
esta intentando representar elementos en un dominio de pintura, el segundo, que
el programador esta pensando en algun juego de ciencia-ficcion, por ejemplo,
y el tercero puede tratarse de cualquier cosa, ya que la intencion original del
programador se ha perdido.
A partir de este ejemplo, podemos ver que el nombre A para un procedimiento
rara vez es adecuado. De la misma forma, un nombre excesivamente largo, como
PonerAlienigenaInvasorCuandoSeProduceLaInvasionALaTierra,
resulta inadecuado pues poco contribuye a la legibilidad del codigo, e incluso lo
complica un poco.
Elegir nombres adecuadamente es, entonces, una cuestion de estilo de fun-
damental importancia. Y como todo estilo, es complejo poder dominarlo. Requie-
re practica, mucha practica. Pero se consigue. En G OBSTONES elegimos la con-
vencion de usar identificadores que comienzan con verbos en infinitivo, seguidos
de alguna descripcion adicional, como Poner, DibujarLinea, etc. Otros lenguajes
siguen otras convenciones.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


63

Como dijimos antes, ningun nombre que se elija esta realmente mal, pues
no es importante para la ejecucion del programa, sino que es mas adecuado o
mas inadecuado para la lectura; y el grado de adecuacion depende mucho del
gusto del que lo lee. Sin embargo, al evaluar un programa, existen elecciones
claramente incorrectas pues no solo no contribuyen a la legibilidad, sino que
confunden. Por ejemplo, observe el siguiente codigo
procedure PonerBolitaRoja() { Sacar(Verde) }
procedure Main() { Poner(Verde); PonerBolitaRoja() }
Que hace este programa? Es correcto? Se da cuenta que la eleccion del
nombre PonerBolitaRoja es terriblemente inadecuada, porque lleva a pensar
en otra idea? Pero sin embargo el codigo funciona! Entonces diremos que este
codigo esta mal, porque su eleccion de nombres es enganosa, aunque el codigo
funcione.
Leer con Atencion

Lo que sucede es que no es suficiente que el codigo funcione para ser


considerado un buen codigo. Debe ser posible que las personas otros
programadores lo lean y entiendan el proposito del mismo. La correc-
ta eleccion de nombres contribuye enormemente a esto. Por correcta,
queremos decir que refleje una adecuacion entre el problema que se
esta resolviendo y la forma de resolverlo, que de cuenta de las intencio-
nes del autor.

Y que hacemos cuando el nombre no es suficiente para mostrar nuestros proposi-


tos? Como damos cuenta, por ejemplo, de la precondicion de un procedimiento?
A continuacion se aborda este tema.

2.3.3. Comentarios en el codigo


Puesto que la intencion del programador no siempre es evidente a partir de la lec-
tura exclusiva de los comandos, incluso a pesar de la adecuada indentacion del
codigo y de la buena eleccion de identificadores, G OBSTONES (al igual que practi-
camente todos los lenguajes) ofrece una posibilidad interesante: la de comentar
el codigo. Comentar el codigo significa agregarle descripciones, llamadas comen-
tarios que no son relevantes para el cabezal, pero que s lo son para un lector
humano. Normalmente estos comentarios se escriben en castellano (o ingles, o
algun otro lenguaje natural), o bien en algun lenguaje formal, como puede ser la
logica. Los comentarios no tienen ningun efecto sobre las acciones del cabezal y
son considerados igual que los caracteres de espacio desde el punto de vista de
la herramienta.
Definicion 2.3.2. Un comentario es una descripcion en castellano o algun len-
guaje formal que se agrega al codigo para mejorar su comprension por parte de
un lector humano. Los comentarios no tienen efecto alguno sobre el accionar del
cabezal.

En G OBSTONES, los comentarios se dividen en dos grupos:


los comentarios de lnea, y
los comentarios de parrafo.
Un comentario de lnea comienza con el smbolo -- o con el smbolo // y con-
tinua hasta el final de la lnea actual; todo lo que se escriba desde el smbolo

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


64

hasta el final de lnea es ignorado durante la ejecucion. Un comentario de parrafo


comienza con el smbolo {- y continua hasta la primera aparicion del smbolo
-}, o comienza con el smbolo /* y continua hasta la aparicion del smbolo */;
todo el texto que aparece enmarcado entre estos pares de smbolos es ignorado
durante la ejecucion.
Los comentarios son utiles para una serie de propositos diferentes. Por ejem-
plo:

describir la intencion de un procedimiento (o cualquier parte del codigo), es


decir su comportamiento esperado;

describir la intencion de un parametro, el conjunto de sus valores posibles,


Todava no hemos hablado de o lo que se intenta representar con el;
parametros. Es un tema que se tra-
tara en la Unidad siguiente. eliminar temporalmente un comando para probar el programa sin el, pero
sin borrarlo del mismo;

brindar informacion diversa acerca del codigo, como ser el autor del mismo,
la fecha de creacion, etcetera.

Como ejemplo de uso de comentarios, se ofrece una version comentada del


procedimiento DibujarLineaHaciaElNorte.

{-
Autor: Fidel
Fecha: 08-08-08
-}
procedure DibujarLineaHaciaElNorte()
{-
PRECONDICION:
Debe haber al menos dos celdas al Norte de la actual.
(O sea, el cabezal no puede encontrarse ni en la ultima
ni en la anteultima fila)
-}
{
-- No se dibuja en la celda incial
Mover(Norte); Poner(Negro) -- Dibuja en la celda
-- al Norte de la inicial
Mover(Norte); Poner(Negro) -- Dibuja en la celda dos
-- lugares al Norte de la
-- inicial

-- Al terminar el cabezal se encuentra dos lugares


-- al Norte de donde comenzo
}

Observar que el codigo efectivo (aquel que no sera ignorado durante la ejecucion)
es identico al ofrecido antes. Sin embargo, los comentarios ayudan a entender el
proposito de cada parte.
Es importante destacar que, puesto que los comentarios son ignorados en la
ejecucion, debe verificarse al leer un programa que los comentarios sean validos
respecto de los comandos. Es una practica mala, pero demasiado comun, el de-
jar comentarios desactualizados al modificar codigo. Por ejemplo, supongamos
que utilizamos este ultimo procedimiento comentado como base para un proce-
dimiento similar utilizado en la solucion del ejercicio 2.2.7. Para ello, copiamos el
programa en otro archivo, y realizamos algunas modificaciones, para obtener:

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


65

{-
Autor: Fidel
Fecha: 08-08-08
-}
procedure DibujarLineaHaciaElNorte()
{-
PRECONDICION:
Debe haber al menos dos celdas al Norte de la actual.
(O sea, el cabezal no puede encontrarse ni en la ultima
ni en la anteultima fila)
-}
{
-- No se dibuja en la celda incial
Mover(Norte); Poner(Negro) -- Dibuja en la celda
-- al Norte de la inicial
Mover(Norte); Poner(Negro) -- Dibuja en la celda dos
-- lugares al Norte de la
-- inicial
Mover(Norte); Poner(Negro) -- Dibuja en la celda dos
-- lugares al Norte de la
-- inicial

-- Al terminar el cabezal se encuentra dos lugares


-- al Norte de donde comenzo
}

Observar que el codigo fue obtenido copiando y pegando (suele decirse, con
cut&paste), y luego alterando algunas partes
Para Reflexionar

Puede encontrar las partes que se agregaron? .

Estas alteraciones llevan a que haya por lo menos tres comentarios desactualiza-
dos en este codigo. El primero es la precondicion, puesto que al agregar coman-
dos de movimiento, la precondicion cambio, y sin embargo el comentario no fue
alterado. El segundo es el comentario de lnea que se asocia al tercer grupo de
comandos: como fue obtenido por cut&paste y no fue modificado, indica lo mismo
que el anterior, pero su efecto es diferente. El tercero es el comentario de cierre, La forma en que la mayora lo lee-
sobre la posicion final del cabezal. Si ademas este codigo hubiera sido modifi- mos es catan peist.
cado por otra persona diferente de Fidel, o en otra fecha, el comentario sobre
el autor y la fecha tambien estaran desactualizados. Puede verse en el grafi-
co G.2.10 las indicaciones de que comentarios estan desactualizados. Puesto
que los comentarios estan en lenguaje natural, y el proposito de un programador
no es analizable automaticamente, este tipo de situaciones no se pueden detec-
tar en ninguna herramienta. Es absoluta responsabilidad del programador que
sus comentarios esten actualizados, sean pertinentes y utiles.
La practica de comentar el codigo de manera adecuada es extremadamen-
te importante cuando varias personas trabajan sobre un programa, ya sea si-
multaneamente, o a lo largo de algun perodo de tiempo. Es recomendable co-
mentar todo codigo que se escriba de manera correcta. Por otra parte, los comen-
tarios desactualizados son mas daninos que la ausencia de comentarios, puesto
que pueden inducir a ideas incorrectas. Es por ello recomendable no desestimar

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


66

G.2.10. Codigo con comentarios desactualizados

la importancia de los comentarios y actualizarlos al modificar el codigo.


Como observaciones finales, salvo que cada procedimiento sea definido por
un programador diferente, la informacion de autor y fecha suele ponerse una
unica vez por archivo o conjunto de definiciones, y no como parte de cada proce-
dimiento. Ademas, rara vez suele comentarse un codigo tan profusamente como
el ejemplo de DibujarLineaHaciaElNorte como hemos hecho aqu.

2.4. Ejercitacion
En este apartado se enuncian una serie de ejercicios de practica adicionales a
los ya dados durante la Unidad. Para su correcta resolucion son necesarios todos
los elementos aprendidos en los apartados anteriores. A traves de su resolucion
iremos repasando algunos de los conceptos principales, e incorporando pregun-
tas que prepararan el material de unidades posteriores.
Actividad de Programacion 12

Realice los ejercicios enunciados en este apartado. Recuerde separar


adecuadamente su codigo en procedimientos, elegir convenientemente
los nombres de los mismos, y comentar su codigo de manera que el
mismo sea facilmente entendible.

El primer ejercicio es simplemente una gua para recordar como definir un pro-
cedimiento, para experimentar como probarlo en un Main, y para preparar ideas
que luego se utilizaran en ejercicios posteriores.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


67

Ejercicio 2.4.1.

Escribir un procedimiento PonerUnaDeCadaColor, que coloque una bolita de cada


color en la celda actual. Cual es su precondicion?

Leer con Atencion

Recuerde que para probar su procedimiento debe escribir un programa


principal que lo utilice.

El siguiente ejercicio permite volver a repasar la idea de reutilizacion de proce-


dimientos ya definidos. Toda vez que una tarea de programacion aparece una
y otra vez, hay un candidato para introducir un procedimiento que resuelva esa
tarea. En muchos casos en este cuadernillo, los procedimientos a utilizar en una
solucion se presentan antes en otros ejercicios previos, orientando de esta ma-
nera la solucion deseada.

Ejercicio 2.4.2.

Escribir el procedimiento Poner5DeCadaColor que coloque cinco bolitas de cada


color en la celda actual. Reutilizar el procedimiento definido en el ejercicio 2.4.1
( PonerUnaDeCada) para definir esta tarea.

Para Reflexionar

Cuanto mas difcil habra sido el ejercicio 2.4.2 si no hubiera conta-


do con el ejercicio 2.4.1? Piense en la necesidad de identificar estas
subtareas, y definir sus propios procedimientos para expresarlas, espe-
cialmente cuando no se hayan definido en ejercicios previos.

Leer con Atencion

Recuerde que una vez que definio la forma de realizar una tarea, siempre
puede reutilizar dicha definicion en ejercicios posteriores. Al probar su
programa no olvide incluir todas las definiciones necesarias en el mismo.

En los proximos dos ejercicios se repasa la idea de precondicion, y de nombrar


adecuadamente, y se trabaja con las ideas de definicion de nomenclatura y de
minimizacion de efectos de un procedimiento. La definicion de nomenclatura es
necesaria para poder hablar de un problema en los terminos del dominio del mis-
mo, y no en terminos de bolitas, y es algo usual en los ejercicios mas complejos.
La minimizacion de efectos de un procedimiento tiene que ver con el hecho de
que el mismo haga lo pedido y nada mas que lo pedido.

Ejercicio 2.4.3.

La celda lindante en direccion < dir > es la primera celda en la direccion dada,
a partir de la celda actual. Por ejemplo la celda lindante al Norte es la primera
celda al Norte de la celda actual.
Escribir el procedimiento PonerAzulAlNorteYMoverse que ponga una bolita
de color azul en la celda lindante al Norte y se quede en esa posicion. Este pro-
cedimiento siempre funciona? Que requerimientos debe cumplir? Cual sera
su precondicion?

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


68

Ejercicio 2.4.4.

Escribir el procedimiento PonerAzulAlNorte que ponga una bolita de color azul


en la celda lindante al Norte pero deje el cabezal en la posicion original. Cual
es su precondicion?

Para Reflexionar

Por que puede ser importante devolver el cabezal? Reflexione sobre


este hecho antes de continuar. Reflexione tambien sobre las diferencias
en el nombre de los procedimientos de los ejercicios 2.4.3 y 2.4.4. Por
que no llamamos al segundo PonerAzulAlNorteYQuedarseEnElLugar?
Recuerde la minimizacion de efectos.

Ejercicio 2.4.5.

Escribir el procedimiento PonerAzulEnLos4Vientos que ponga una bolita de co-


lor azul en la celda lindante al Norte, Sur, Este y Oeste y deje el cabezal en la
posicion original. Cual es la precondicion del procedimiento?

Para Reflexionar

Como habra sido la solucion del ejercicio 2.4.5 si en lugar de usar


la solucion del ejercicio 2.4.4, hubiera utilizado la del ejercicio 2.4.3?
Reflexione acerca de como algunas decisiones sobre que tareas agrupar
en cada procedimiento pueden afectar la complejidad de la solucion final.

En el siguiente ejercicio trabajamos con la idea de dominio de un problema, re-


pasando la idea de definicion de nomenclatura. En este caso, si estamos cons-
truyendo un programa de pintura, tiene sentido hablar de temperas de colores y
no de bolitas, y representar y nombrar las ideas de manera adecuada al proble-
ma y no al lenguaje de programacion. Tambien se repasa la idea de que usted
identifique sus propias subtareas, definiendo procedimientos para ellas.
Leer con Atencion

Al realizar el ejercicio, recuerde definir procedimientos auxiliares (como


PonerUnaDeCadaColor en el caso de Poner5DeCadaColor), con los cua-
les definir sus procedimientos le resulte sencillo. Para ello, intente iden-
tificar subtareas y nombrarlas adecuadamente.

Ejercicio 2.4.6. Supongamos que representamos a 1 gota de tempera con 3 bo-


litas de un color determinado. Escribir el procedimiento Mezclar2GotasDeAmarillo
que agregue en la celda actual 1 gota de tempera azul y 1 gota de tempera verde.

Para Reflexionar

Que tan adecuado es el nombre Mezclar2GotasDeAmarillo? Como


denomino a sus procedimientos auxiliares? Nombres adecuados
habran sido Poner1GotaDeAzul y Poner1GotaDeVerde. No sera me-
jor nombrar de otra forma al procedimiento Mezclar2GotasDeAmarillo?

El siguiente ejercicio insiste sobre la idea de reuso de procedimientos, y trabaja

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


69

sobre la adecuacion de nombrar a los procedimientos de determinada manera.


Ejercicio 2.4.7.

Escribir el procedimiento Poner3GotasDeNaranja que agregue en la celda actual


1 gota de tempera amarilla y 1 gota de tempera roja. Para resolver este ejercicio,
debe cambiarse el nombre del procedimiento del ejercicio 2.4.6 convenientemen-
te para lograr uniformidad y adecuacion en los nombres.

El uso uniforme de nombres esta relacionado con la comprension del problema


a resolver, y su adecuada expresion en terminos de los elementos del lenguaje
de programacion. Representar bien las ideas basicas del problema en terminos
de procedimientos hace que luego la solucion resulte sencilla de entender y mo-
dificar. Por ejemplo, si uno quisiera cambiar la representacion, solo tendra que
cambiar los procedimientos mas elementales.
Ejercicio 2.4.8.

Modificar el procedimiento Poner3GotasDeNaranja para que la representacion de


1 gota de tempera de color sea realizada con 5 bolitas en lugar de 3. Que proce-
dimientos fue necesario modificar? Debio alterarse el codigo del procedimiento
Poner3GotasDeNaranja, o basto con modificar los procedimientos elementales?

Para Reflexionar

Cuando las subtareas fueron identificadas adecuadamente y expresa-


das correctamente en terminos de procedimientos, modificaciones en la
representacion no deberan afectar la solucion en su nivel mas cercano
al problema. Si en lugar de 3 o 5 bolitas para representar una gota, hu-
bieramos elegido 1, habra seleccionado un procedimiento para repre-
sentar la idea de poner una gota? Si su respuesta es no, reflexione sobre
lo sencillo que es caer en el pensamiento operacional, que se concentra
en las operaciones individuales en lugar de en las tareas a resolver, y en
las terribles consecuencias de esto en la calidad del codigo producido.

Los proximos ejercicios repasan las siguientes ideas:


la correcta identificacion de subtareas reduce significativamente la com-
plejidad del codigo resultante y facilita su modificacion ante cambios en la
representacion;
el adecuado uso de nombres de procedimientos mejora la legibilidad y fa-
cilita la comprension de dicho codigo; y
la minimizacion de los efectos de un procedimiento permite que su combi-
nacion con otros sea mas sencilla.
Ejercicio 2.4.9.

Completar los procedimientos necesarios para que el procedimiento LetraERoja


pinte una letra E con acuarela roja, suponiendo que en cada celda se coloca
una gota de acuarela, y que una gota de acuarela se representa con 1 bolita. La
letra E se puede pintar en un grupo de 5 por 3 celdas, como se muestra en el
grafico G.2.11a y un posible codigo para el procedimiento LetraERoja sera
procedure LetraERoja()
{- PROPOSITO: pinta una letra E roja en el tablero

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


70

(a). Letra E roja (b). Letra E marron

G.2.11. Representacion de distintas letras E en el tablero de G OBSTONES

PRECONDICION: Hay 4 celdas al Norte y


2 al Este de la celda actual
OBSERVACION: No modifica la posicion del cabezal
-}
{
PintarLineaHorizontal3() -- La base de la E
Mover(Norte)
PintarCelda() -- Nivel 2 de la E
Mover(Norte)
PintarLineaHorizontal3() -- La barra de la E
Mover(Norte)
PintarCelda() -- Nivel 4 de la E
Mover(Norte)
PintarLineaHorizontal3() -- El tope de la E
-- Retorna el cabezal
Mover(Sur);Mover(Sur);Mover(Sur);Mover(Sur)
}

Para Reflexionar

Observe con detenimiento los procedimientos que utilizamos en el pro-


cedimiento LetraERoja, y como los mismos fueron comentados. Al iden-
tificar correctamente las partes se requieren pocos procedimientos, y el
codigo resultante queda estructurado con base en el problema, y no en
las celdas en las que se dibuja. Reflexione sobre como habra sido el
codigo si en lugar de definir y usar PintarLineaHorizontal3, hubiera
usado solo PintarCelda y Mover. Y si PintarLineaHorizontal3 hicie-
se mas de lo mnimo necesario?

Ejercicio 2.4.10.

Escribir un procedimiento LetraE, que pinte una letra E con acuarela marron,

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


71

G.2.12. Representacion de dos letras E en el tablero de G OBSTONES

suponiendo que la acuarela marron se consigue mezclando una gota de cada


uno de los 4 colores. La letra E debera quedar como se muestra en el grafi-
co G.2.11b. Ayuda: Modificar adecuadamente el ejercicio anterior. Puede ha-
cerse con solo 2 cambios y a lo sumo 4 procedimientos nuevos? Uno de los cam-
bios es modificar el nombre del procedimiento LetraERoja por LetraE. Cual
debera ser el otro? Que procedimientos nuevos definir para la representacion?
El siguiente ejercicio motiva la necesidad de alguna herramienta del lenguaje
que permita separar de alguna manera, por un lado el dibujo de una letra, y por
el otro la eleccion sobre el color con la que se la dibuja. Esta herramienta se
vera en unidades posteriores.
Ejercicio 2.4.11.

Escribir un procedimento LetrasERojaYNegra que dibuje una letra E roja seguida


de una letra E negra. El dibujo debera quedar como en el grafico G.2.12.
Sugerencia: utilizar como base para la solucion de este ejercicio, el codigo
dado en el ejercicio 2.11a, duplicandolo y cambiando lo necesario en la version
duplicada para tener una letra E negra ademas de la roja.

Para Reflexionar

Con los elementos presentados en esta Unidad, la unica alternativa para


resolver el ejercicio 2.4.11 es duplicar el codigo y cambiar el color con el
que se dibuja. Eso obliga a duplicar todos los procedimientos auxiliares,
y buscar nuevos nombres para cada uno. Se da cuenta como es im-
prescindible, para poder hacer un programa razonable, contar con algun
elemento que permita evitar esta duplicacion?

Ejercicio 2.4.12.

Escribir un procedimiento DibujarTrianguloBase7 que dibuje un triangulo verde


que tenga una base de 7 celdas. No utilizar mas de 3 comandos en el cuerpo del
procedimiento definido. El dibujo debe quedar como en el grafico G.2.13.
Ayuda: para lograrlo hay que pensar en 3 subtareas que consigan dibujar las
3 partes de un triangulo. . . No olvidar escribir las precondiciones de cada uno!

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


72

G.2.13. Dibujo de un triangulo de base 7

Para Reflexionar

En este caso, no era conveniente que las subtareas dejasen inalterada la


posicion del cabezal, puesto que al dibujar, estamos simulando un lapiz.
Hemos intentado expresar esta sutileza utilizando el termino Dibujar en
lugar de Poner. Esto es conveniento expresarlo en las observaciones
del procedimiento, como comentario.

Leer con Atencion

Si calculo bien las precondiciones de los procedimientos auxiliares y del


que dibuja el triangulo, podra observar que no todos los requisitos de los
auxiliares aparecen en el procedimiento general. Por ejemplo, dibujar la
lnea izquierda requiere espacio al Este, pero puesto que los dibujos
anteriores se movieron hacia el Oeste, ese lugar existe seguro. Las pre-
condiciones son una herramienta poderosa, pero en los casos complejos
puede ser difcil calcularlas con exactitud. Por esa razon en este curso
las usamos solo como gua y de manera relativamente informal.

El siguiente ejercicio motiva nuevamente la necesidad de alguna herramienta del


lenguaje que permita separar el dibujo de una figura del tamano de la misma.

Ejercicio 2.4.13.

Escribir un procedimiento DibujarArbol, que dibuje un arbol de tipo confera,


como se muestra en el grafico G.2.14.
Ayuda: basarse en el procedimiento del ejercicio 2.4.12. Copiarlo 3 veces y
modificar cada copia para obtener triangulos de distintos tamanos. Luego dibujar
cada pieza, posicionandose adecuadamente para comenzar cada una.

Para Reflexionar

Nuevamente, con los elementos presentados en esta Unidad, la unica al-


ternativa para resolver el ejercicio 2.4.13 es duplicar el codigo y cambiar
el tamano del dibujo. Todos los procedimientos auxiliares deben duplicar-
se, y buscar nombres adecuados para cada uno de ellos. Se da cuenta
como es imprescindible, para poder hacer un programa razonable, con-
tar con algun elemento que permita evitar esta duplicacion?

El siguiente ejercicio busca practicar los conceptos adquiridos.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


73

G.2.14. Dibujo de un arbol de tipo confera

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


74

Ejercicio 2.4.14.

Supongamos que cada celda del tablero representa una seccion del cantero de 1
metro de longitud. Ademas, representaremos flores con combinaciones de boli-
tas. Las rosas se representan con 1 bolita de color rojo, las violetas se represen-
tan con 1 bolita de color azul, y los girasoles se representan con 1 bolita de color
negro. Se desea armar un cantero de flores de 3 metros de longitud, donde cada
metro del cantero posee 5 rosas, 8 violetas y 3 girasoles.
Escribir el procedimiento ArmarCantero que cumpla con esta representacion.

Para Reflexionar

Uso procedimientos auxiliares? Comprende la manera importantsima


en la que los mismos permiten simplificar la comprension del programa
y su analisis de correccion? Si no lo hizo, observe la complejidad del
codigo que resulta, y repita el ejercicio usando procedimientos auxiliares.

Ejercicio 2.4.15.

Modificar el programa del ejercicio 2.4.14 para que ahora las flores se represen-
ten utilizando el siguiente esquema. Las rosas se representan con 3 bolitas de
color rojo y 1 de color negro, las violetas se representan con 2 bolitas de color
azul y 1 de color rojo, y los girasoles se representan con 3 bolitas de color negro
y 2 de color verde.

Para Reflexionar

Le resulto facil la modificacion? Si no, revise los conceptos de separa-


cion en procedimientos y de representacion de informacion.

El ultimo ejercicio busca combinar todos los elementos vistos hasta ahora. Por un
lado, usted debe decidir acerca de la representacion de los elementos. Por otro,
debera utilizar adecuadamente procedimientos para representar cada parte, no
solo la representacion de los elementos, sino tambien las acciones involucradas.
Finalmente, debe establecer las precondiciones necesarias, y al probarlo, ga-
rantizar que las mismas se cumplen de alguna manera. No olvide comentar el
codigo!

Ejercicio 2.4.16.

La Base Marambio, en la Antartida, esta siendo invadida por extraterrestres de


color verde. La base es de color azul y esta totalmente rodeada por ellos en las 8
direcciones del radar. La mision es escribir un programa G OBSTONES que mues-
tre como eliminar la amenaza aliengena. Para ello hay que representar de alguna
manera la informacion del radar en el tablero de G OBSTONES, y luego escribir el
procedimiento AcabarConAmenazaAlienigena que elimine a los invasores. Cual
sera la precondicion de este procedimiento?
Ayuda: De que manera podra ser representado un aliengena en el radar?
Y la base? Imaginar una representacion para cada uno de estos objetos, inten-
tando ser fiel a la descripcion dada sobre ellos, y elegir la representacion mnima
necesaria.
La manera de eliminar a los invasores estara relacionada con la forma en la
que son representados si, por ejemplo, un elemento se representa utilizando 2

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


75

bolitas de color negro, la forma de eliminarlos debera ser quitar esa cantidad de
bolitas de ese color.

Para Reflexionar

Pudo probar el procedimiento anterior? Que mecanismo eligio para


garantizar la precondicion de AcabarConAmenazaAlienigena al invocarlo
desde Main? Tenga en cuenta que en ocasiones utilizar las ventajas que
nos proveen las herramientas simplifica mucho el trabajo. Utilizo la idea
de precondicion para armar el tablero de ejemplo?

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


76

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


77

Procedimientos, funciones y
parametrizacion

En la Unidad anterior vimos los bloques basicos de un lenguaje de programacion


(expresiones, comandos y procedimientos simples, y las cuestiones de estilo), en
la presente Unidad procederemos a ver como hacer bloques mas poderosos, y
estudiaremos el concepto de parametrizacion. En el proceso, agregaremos algu-
nas formas basicas de combinacion de comandos y expresiones.

3.1. Procedimientos
En la Unidad anterior aprendimos como escribir procedimientos simples (defini-
cion 2.2.9), y trabajamos con ellos, aprendiendo como utilizarlos adecuadamen-
te. Vimos que los procedimientos simples eran una forma de nombrar coman-
dos compuestos para identificarlos como tareas de nuestro problema. Y tambien
vimos que ademas de los comandos, los lenguajes posean expresiones para
describir valores, entidades para representar informacion.
En este apartado vamos a agregar la idea de parametro a los procedimientos,
y comenzaremos a estudiar su potencial.

3.1.1. Procedimientos con parametros


Al resolver el problema de dibujar un cuadrado fue necesario escribir cuatro pro-
cedimientos, uno para cada una de las lneas. Sin embargo, lo unico que va-
riaba de uno a otro (ademas del nombre), era la direccion en la que el cabezal
deba desplazarse. El programa para dibujar un cuadrado queda como en el grafi-
co G.3.1 donde se indica, justamente, que la unica diferencia entre los procedi-
mientos para dibujar lneas es la direccion en la que debe moverse el cabezal al
comenzar.
Pero tener cuatro procedimientos unicamente porque un valor determinado
es diferente es poco eficiente, ya que para modificarlos habra que hacerlo uno
por uno, y esto podra resultar en diferentes errores en cada uno. Resulta mucho
mas conveniente contar con alguna forma de representar esos cuatro procedi-
mientos en uno solo, e indicarle, de alguna manera, que direccion queremos que
tenga en cuenta en cada uso. Podramos pensar en este nuevo procedimiento
como un esquema o template, o sea, un procedimiento con un agujero a ser re-
llenado. Segun el valor que eligiesemos para rellenar el agujero, podramos tener
diferentes procedimientos. Este proceso se ilustra en el grafico G.3.2.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


78

G.3.1. Programa que dibuja un cuadrado negro, con 4 procedimientos para las
lneas

G.3.2. Relacion entre los procedimientos de dibujar lneas y un esquema de pro-


cedimiento

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


79

Leer con Atencion

Sin embargo, el agujero no puede expresarse graficamente en un len-


guaje de programacion. Para poder expresarlo se utiliza un mecanismo
conocido con el nombre de parametro. Un parametro es un nombre que
denota un valor que puede ser diferente cada vez que se usa un proce-
dimiento, y que debe ser suministrado en la invocacion como un valor
concreto.

En nuestro ejemplo, sera el nombre del agujero, direccion, que adoptara un


valor diferente cada vez que fuese usado el procedimiento DibujarLineaHaciaEl.
As, en lugar de escribir un agujero graficamente, usaremos un nombre que indi-
ca que ah hay un agujero. Ese nombre aparecera en el encabezado del proce-
dimiento, como se ve en el siguiente codigo:
procedure DibujarLineaHaciaEl(direccion)
{-
PROPOSITO:
* dibuja una lnea de longitud 1 en la
direccion dada
PRECONDICION:
* hay una celda lindante en la
direccion dada
-}
{ Mover(direccion); Poner(Negro) }
El nombre direccion mencionado en el encabezado del procedimiento indica
que este procedimiento tiene un agujero con ese nombre, como se ilustra en el
primer procedimento del grafico G.3.3.
As, un parametro es un nombre que denota un valor, el cual cambia en cada
llamado al procedimiento. La forma de definir un parametro es utilizar un iden-
tificador entre parentesis luego del nombre del procedimiento. Ese identificador
puede luego ser utilizado dentro del bloque que define el procedimiento como si
de un valor fijo se tratase; al utilizarlo es como si hubiesemos llenado el agujero
nombrado por el parametro con el valor especfico.
Definicion 3.1.1. Un parametro es un identificador que denota a un valor que
puede ser diferente en cada invocacion de un procedimiento. La forma de definir
procedimientos con parametros es
procedure < procName >(< params >)
< bloque >
donde < params > es una lista de identificadores separados por comas. Los iden-
tificadores usados como parametros deben comenzar con minuscula.

Leer con Atencion

El parametro por s solo no tiene sentido. Debe asociarse a un valor


concreto en cada invocacion. Este valor concreto usado en la invocacion
recibe el nombre de argumento.

Definicion 3.1.2. Un argumento es el valor especfico usado en la invocacion


de un procedimiento con parametros. Al invocar un procedimiento, se utiliza la
siguiente forma

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


80

G.3.3. Programa que dibuja un cuadrado negro con un unico procedimiento pa-
rametrizado para dibujar lneas

< procName >(< args >)


donde < args > es una lista de valores especficos (los argumentos) para los
parametros.

El argumento aparece entre parentesis al invocar un procedimiento con parame-


tros. Esta es la forma de indicar que el valor del argumento debe ser utilizado en
el lugar donde se coloco el agujero nombrado por el parametro. Este proceso se
ilustra en el grafico G.3.3.
Puede verse que es mas conveniente escribir un solo procedimiento para
dibujar las lneas que reciba la direccion como parametro, y que sea el procedi-
miento de dibujar el cuadrado el que se encargue de utilizar el mismo procedi-
miento, pero con diferentes datos. El codigo completo, incluyendo comentarios,
quedara:
procedure DibujarLineaHaciaEl(dir)
{- PROPOSITO:
* dibuja una lnea de longitud 1 de color Negro
PRECONDICION:
* el parametro dir es una direccion
* existe al menos una celda en la direccion dada
por el parametro dir
-}
{
Mover(dir); Poner(Negro)
}

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


81

procedure CuadradoNegro()
{- PROPOSITO:
* dibuja un cuadrado Negro de lado 2
PRECONDICION:
* el cabezal no se encuentra ni en la ultima fila
ni en la ultima columna
-}
{
DibujarLineaHaciaEl(Norte)
DibujarLineaHaciaEl(Este)
DibujarLineaHaciaEl(Sur)
DibujarLineaHaciaEl(Oeste)
}
que es mucho mas conciso, ya que evita la repeticion del codigo de dibujar lneas
solo para tener diferentes direcciones. Observar que dir es el parametro en la
definicion de DibujarLineaHaciaEl y se lo utiliza en el comando Mover(dir);
el nombre utilizado no es importante, pero debe indicar de alguna manera la
intencion de para que se utilizara el parametro. Al invocar el procedimiento pa-
rametrico DibujarLineaHaciaEl se utiliza un valor especfico de direccion como
argumento en cada caso. El codigo final es equivalente al codigo original, pero
que define solo dos procedimientos, en lugar de cinco!
El mecanismo utilizado para esta definicion, llamado abstraccion, consiste en
concentrarse en las similaridades entre diferentes elementos, reconociendolos
como casos particulares de una misma idea. El uso de parametros permite iden-
tificar en que partes son diferentes los elementos, y el proceso de invocacion
de un procedimiento con argumentos (valores especficos para los parametros)
permite obtener los elementos particulares a partir de la definicion general. Este
caso particular de abstraccion se conoce con el nombre de parametrizacion, por
el uso de parametros para representar las variaciones de una misma idea.
Que otras nociones son generalizables en el caso de dibujar un cuadrado?
La mas sencilla de todas es el color del cuadrado. El programa definido dibu-
ja un cuadrado negro. Si quisieramos un cuadrado rojo o uno azul, tendramos
que definir otro procedimiento que utilice a su vez un procedimiento que dibu-
je una lnea con la instruccion Poner(Rojo) o Poner(Azul), en lugar de la ac-
tual Poner(Negro). Sin embargo, la unica diferencia entre estos procedimientos,
que dibujan cuadrados de distintos colores, es el color elegido para pintar cada
cuadrado, lo que nos permite parametrizar su color y disenar un procedimiento
general que dibuje un cuadrado de un color que elijamos al invocarlo.
Volviendo al codigo original con cinco procedimientos para dibujar el cuadra-
do, el codigo para generalizar el cuadrado de diferentes colores podra definirse
utilizando procedimientos como los siguientes:
procedure DibujarLineaHaciaNorteDeColor(color)
{- PROPOSITO:
* dibuja una lnea del color indicado de longitud
1 hacia el Norte
PRECONDICION:
* el parametro color es un color
* existe al menos una celda en al Norte
-}
{
Mover(Norte); Poner(color)

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


82

procedure DibujarCuadrado()
{- PROPOSITO:
* dibuja un cuadrado Negro de lado 2
PRECONDICION:
* el cabezal no se encuentra ni en la ultima fila
ni en la ultima columna
-}
{
DibujarLineaHaciaNorteDeColor(Negro)
DibujarLineaHaciaEsteDeColor(Negro)
DibujarLineaHaciaSurDeColor(Negro)
DibujarLineaHaciaOesteDeColor(Negro)
}

donde deben aun definirse los procedimientos DibujarLineaHaciaEsteDeColor,


DibujarLineaHaciaSurDeColor y DibujarLineaHaciaOesteDeColor, parametri-
zados adecuadamente con un color, siguiendo el mismo patron que en la defi-
nicion de DibujarLineaHaciaNorteDeColor. Es claro que es mucho mejor si se
parametrizan ambas nociones, el color y la direccion.
Actividad de Programacion 1

Realizar el ejercicio 3.1.1, y probarlo dibujando cuadrados de al menos 3


colores en 3 posiciones diferentes del tablero. Recordar que para probar
un ejercicio debe escribir un procedimiento Main que invoque adecuada-
mente los procedimientos necesarios.

Ejercicio 3.1.1. Definir un procedimiento DibujarCuadradoDeColor que, dado


un color como parametro, dibuje un cuadrado de lado dos de dicho color, utilizan-
do un unico procedimiento para dibujar lneas.

Otra nocion generalizable es el tamano del cuadrado. Sin embargo, para poder
generalizarla son necesarios comandos mas complejos, por lo cual esta idea se
tratara luego de presentar dichos comandos, en el Apartado siguiente.
Un detalle importante a observar en el uso de parametros es la correspon-
dencia entre el numero de parametros declarados en un procedimiento, y el
numero de argumentos usados para invocarlo. Por ejemplo, el procedimiento
DibujarLineaHacia tiene un unico parametro dir y cuando se invoca dicho pro-
cedimiento se debe suministrar un unico valor; es valido invocar al procedimiento
como DibujarLineaHacia(Norte), as como tambien con el resto de las direc-
ciones. La misma correspondencia debe existir si se usan varios parametros en la
definicion del procedimiento: al invocarlo deben usarse la misma cantidad de ar-
gumentos. Si tomamos el procedimiento de dibujar lneas utilizado en la solucion
al ejercicio 3.1.1

procedure DibujarLineaDeHacia(color,dir)
{- PROPOSITO:
* dibuja una lnea de longitud 1 del color indicado
y en la direccion indicada
PRECONDICION:
* el parametro dir es una direccion y color es un color

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


83

* existe al menos una celda en la direccion dada por dir


-}
{
Mover(dir); Poner(color)
}

vemos que DibujarLineaDeHacia(Negro,Norte) es una invocacion valida del


procedimiento DibujarLineaDeHacia, pues corresponden el numero de los argu-
mentos con los parametros declarados. En cambio una invocacion invalida sera
DibujarLineaDeHacia(Norte), ya que no concuerda la cantidad de argumentos
entre el uso y la declaracion. Otro error posible sera hacer la invocacion con los
parametros invertidos: DibujarLineaDeHacia(Norte,Negro), pues en la defini-
cion el parametro de nombre color se utiliza para invocar al comando Poner, y
si rellenamos dicho parametro con el argumento Norte, eso producira un error (y
lo mismo con Negro, dir y Mover).
Actividad de Programacion 2

Realizar nuevamente los ejercicios 2.4.5 y 2.4.11 de la unidad anterior,


intentando definir la menor cantidad posible de procedimientos auxilia-
res. Utilizar la idea de parametro vista en este apartado.

Una nocion mas a tener en cuenta es donde tiene sentido utilizar un parametro.
Un parametro permite definir un esquema de procedimiento, nombrando un valor
que sera diferente en cada llamado de dicho procedimiento.
Leer con Atencion

Es por tanto razonable esperar que la validez del parametro sea solo
dentro del cuerpo del procedimiento que lo define. Esta nocion de va-
lidez se conoce con el nombre de alcance (en ingles scope), y es ex-
tremadamente importante, pues es usual intentar utilizar un parametro
fuera de su alcance, provocando errores extranos.

Definicion 3.1.3. El alcance de un parametro es la region del programa donde


el mismo tiene validez y puede ser utilizado.

Diferentes herramientas (parametros, variables, etc.) poseen alcance, y la forma


de definirlo vara de herramienta en herramienta y de lenguaje en lenguaje. En
G OBSTONES el alcance es el mas simple de todos, siendo exclusivamente local,
lo cual quiere decir que un parametro solamente es conocido en el cuerpo del
procedimiento que lo define. Podramos entender esto pensando en un procedi-
miento como una familia, y en el nombre del parametro como un apodo familiar:
personas ajenas a la familia no conoceran este apodo, y diferentes familias pue-
den usar el mismo apodo para diferentes personas.
Antes de profundizar en estas nociones, vamos a incorporar algunos elemen-
tos para poder armar ejemplos mas complejos.

3.1.2. Formas basicas de repeticion de comandos


Al pensar en parametrizar el dibujo del cuadrado, surge inmediatamente la idea
de parametrizar su tamano. Esto se hara pasando un parametro numerico que
indicase el tamano esperado del lado del cuadrado. Sin embargo, con las herra-
mientas actuales con las que cuenta el lenguaje no es posible construir ningun

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


84

procedimiento que aproveche un parametro numerico. Por ello, es necesario pre-


sentar una nueva forma de armar comandos compuestos: la repeticion indexada.
En esta forma de repeticion un comando se repite un cierto numero de veces,
siendo ese numero controlado por un ndice que toma valores en un rango fijo.
La forma que se utiliza para definir una repeticion indexada en G OBSTONES es
repeatWith. Por ejemplo, para poner 10 bolitas rojas en la celda actual se puede
escribir el siguiente comando:
repeatWith i in 1..10
{ Poner(Rojo) }
En este caso el rango es 1 2 3 4 5 6 7 8 9 10, y el comando se repetira una
vez por cada elemento del rango. El identificador i es un ndice que nombrara ca-
da uno de los valores del rango en cada repeticion; o sea, en la primera repeticion
i nombrara al 1, en la segunda repeticion i nombrara al 2, etcetera.
Definicion 3.1.4. La repeticion indexada permite repetir una accion un cierto
numero de veces, siendo esta cantidad indicada por un ndice que vara dentro
de un cierto rango de valores. El comando repeatWith que permite la repeticion
indexada tiene la siguiente forma:
repeatWith < indexName > in < inicioRango >..< finRango >
< bloque >
siendo < indexName > un identificador con minuscula que nombra al ndice de la
repeticion, < inicioRango > y < finRango > valores del mismo tipo que establecen
los lmites de dicho ndice, y < bloque > un bloque cualquiera que se repetira.

El efecto de un comando de repeticion indexada es que la accion descrita por


el bloque < bloque > se repetira tantas veces como valores haya en el rango
determinado por < inicioRango > y < finRango >. Por ejemplo, la accion de poner
10 bolitas rojas podra describirse tambien con el comando
repeatWith i in 3..12
{ Poner(Rojo) }
siendo < inicioRango > el valor 3 y < finRango > el valor 12. En este caso el rango
sera 3 4 5 6 7 8 9 10 11 12, y por lo tanto i nombrara a los valores de 3 a 12
en cada repeticion.
El rango siempre debe ser creciente, o sea, el valor inicial debe ser menor
o igual que el valor final y el incremento en este lenguaje es siempre 1. Si el
Diferentes lenguajes poseen dife- valor inicial es mayor que el final, el rango es vaco y el comando de repeticion no
rentes formas de expresar repeti- realiza ninguna accion. Por ejemplo, el siguiente comando no tiene ningun efecto:
cion, y pueden permitir variaciones
como incrementos diferentes de 1, repeatWith i in 10..1
o rangos decrecientes. Sin embar-
go, G OBSTONES solamente posee { Poner(Rojo) }
las formas basicas, para simplificar
su estudio, pues no esta pensado puesto que el rango 10..1 es vaco.
para programar de manera profe- El verdadero poder de la repeticion indexada viene de su combinacion con
sional sino solo como lenguaje ini- parametros. Por ejemplo, se puede definir un procedimiento que coloque n bolitas
cial de aprendizaje.
de color Rojo en la celda actual, a traves del siguiente procedimiento:
procedure PonerNRojas(cantidad)
{- PROPOSITO:
* coloca en la celda actual la cantidad de bolitas rojas
indicada (y ninguna si cantidad<0)
PRECONDICION: ninguna (es una operacion total)
-}

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


85

{
repeatWith i in 1..cantidad
{ Poner(Rojo) }
}
Entonces, el comando PonerNRojas(3) pondra 3 bolitas en la celda actual, y el
comando PonerNRojas(10) pondra 10 bolitas.
Actividad de Programacion 3

Realizar los procedimientos solicitados en el ejercicio 3.1.2. Utilizar el


primero de ellos para colocar 17 bolitas azules y 42 bolitas negras en la
celda actual. Cual es la precondicion del programa?

Ejercicio 3.1.2. Escribir los procedimientos que se describen.


1. PonerN que deposite cant bolitas de color color en la celda actual, supo-
niendo que cant es un numero positivo. Cual es su precondicion?
2. MoverN que se mueva cant celdas en la direccion dir desde la celda actual,
suponiendo que cant es un numero positivo. Cual es su precondicion?
3. SacarN que quite cant bolitas de color color de la celda actual, suponiendo
que cant es un numero positivo. Cual es su precondicion?

Para Reflexionar

Al parametrizar direcciones o colores expresamos 4 procedimientos sim-


ples en uno parametrizado. Sin embargo, al parametrizar cantidades es-
tamos expresando una cantidad infinita de procedimientos simples con
uno solo. Reflexione sobre la necesidad de la repeticion indexada para
conseguir esto, y sobre las limitaciones que impondra el lenguaje de
programacion si no contasemos con la misma. Cuando decimos que al
aprender a programar debemos concentrarnos en ideas importantes nos
estamos refiriendo exactamente a este tipo de imprescindibilidad.

El ndice de una repeticion indexada es un identificador usado para denotar cada


elemento del rango, y por lo tanto, puede utilizarse como un valor en el bloque
que se repite.
Por ejemplo, si se desea colocar 1 bolita roja en la celda actual, 2 en la celda
lindante al Norte, 3 en la siguiente, y as hasta 6 bolitas en la celda a 5 lugares al
Norte de la actual, se puede escribir el siguiente comando
repeatWith cant in 1..6
{ PonerNRojas(cant); Mover(Norte) }
Observar que el ndice, cant en este caso, denota un valor diferente en cada
repeticion del cuerpo. O sea, si el rango es 1 2 3 4 5 6, el valor de cant sera 1
en la primera iteracion, 2 en la segunda, 3 en la tercera, 4 en la cuarta, 5 en la
quinta y 6 en la ultima.
Actividad de Programacion 4

Realizar el ejercicio 3.1.3. Utilizarlo para obtener en el tablero final la


configuracion de bolitas del grafico G.3.4a.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


86

(a). Tablero a producir como resultado. (b). Tablero a producir como variante.

G.3.4. Tableros a producir en el ejercicio 3.1.3

Actividad de Programacion 5

Que tendra que cambiarse en el procedimiento Progresion de la acti-


vidad anterior para obtener la configuracion del grafico G.3.4b?

Ejercicio 3.1.3. Escribir un procedimiento Progresion que dados un numero n


y una direccion dir, coloque 1 bolita roja en la celda actual, 2 bolitas rojas en la
celda lindante en la direccion dir, 3 en la siguiente, etc. repitiendo esto n veces.

Los rangos de una repeticion indexada no se limitan a numeros. Tambien pueden


ser colores, direcciones o booleanos. El orden de las direcciones es en el sentido
de las agujas del reloj, comenzando por el Norte, el orden de los colores es
alfabetico, y el de los booleanos es primero falso y luego verdadero. El orden
en cada caso es importante para saber que rango corresponde a cada par de
valores. Por ejemplo, el procedimiento para dibujar un cuadrado de 2 celdas de
lado puede escribirse de la siguiente manera:
procedure CuadradoNegro()
{- PROPOSITO:
* dibuja un cuadrado Negro de lado 2
PRECONDICION:
* el cabezal no se encuentra ni en la ultima fila
ni en la ultima columna
-}
{
-- OBSERVAR que son direcciones!
repeatWith dir in Norte..Oeste
{ DibujarLineaHacia(dir) }
}
Observar que la repeticion utiliza las direcciones como ndice, y que por el orden
de las mismas, utiliza las 4 direcciones.

Con la repeticion indexada puede realizarse un procedimiento para dibujar


cuadrados de cualquier longitud.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


87

Actividad de Programacion 6

Realizar el ejercicio 3.1.4 y utilizar el procedimiento definido para dibujar


varios cuadrados de distintos tamanos y colores.

Ejercicio 3.1.4. Escribir un procedimiento DibujarCuadrado que dibuje cuadra-


dos de color color y de n celdas de lado. Confirmar que el lado del cuadrado
tenga exactamente n celdas, y no mas o menos (tener en cuenta que las lneas
tienen ancho 1, y el ancho de la lnea que se superpone tambien cuenta para el
total). Utilizar la menor cantidad de procedimientos posible.

3.1.3. Ejercitacion
En este subapartado revisamos algunos de los ejercicios de practica de la Unidad
anterior, con el fin de incorporar las nociones de parametros y repeticion.
Actividad de Programacion 7

Realice los ejercicios enunciados en este subapartado. Recuerde utilizar


todas las buenas practicas que venimos estudiando (adecuada separa-
cion en subtareas, eleccion de buenos nombres de procedimientos y
parametros, indentacion de codigo, reutilizacion de codigo ya realizado,
etcetera).

Ejercicio 3.1.5. Rehacer el ejercicio 2.4.1 usando repeticion. Rehacer el ejerci-


cio 2.4.2 usando repeticion. Generalizarlo a un procedimiento PonerNDeCada que
tome la cantidad como parametro. Recuerde que generalizar un pro-
cedimiento es cambiar algun dato
Para Reflexionar fijo del mismo por un parametro, de
forma tal que con un codigo casi
identico al anterior, ahora se expre-
Puede observar como el uso de repeticion y parametros simplifica el san muchos mas procedimientos.
codigo producido, al tiempo que lo hace mas generalizable? Reflexione
sobre la importancia de contar con adecuadas herramientas abstractas
de programacion, tales como los procedimientos, los parametros y las
estructuras de control como la repeticion.

Ejercicio 3.1.6. Rehacer el ejercicio 2.4.4, pero generalizando el color y la direc-


cion. Usar el resultado para rehacer el ejercicio 2.4.5 generalizando el color, y
usando una repeticion sobre direcciones.
Ejercicio 3.1.7. Rehacer los procedimientos del ejercicio 2.4.9 generalizando el
color con el cual se dibuja la letra E. Rehacer el ejercicio 2.4.10 para que reutilice
el procedimiento anterior y una repeticion sobre colores.

3.2. Expresiones y funciones


En este apartado veremos como definir en G OBSTONES expresiones complejas,
resultantes de combinar otras expresiones. Es algo similiar a lo hecho con co-
mandos a traves de procedimientos definidos por el usuario, es decir, agrupare-
mos y nombraremos expresiones, solo que con una nueva herramienta conocida
como funciones.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


88

3.2.1. Expresiones compuestas y tipos


Las expresiones compuestas son algo familiar cuando hablamos de numeros.
As, sabemos que 2+3 esta formado por tres partes: dos descripciones de nume-
ros y un smbolo que denota la operacion de sumar ambos numeros. En cual-
quier lenguaje de programacion habra diversas formas de armar expresiones
compuestas que vendran dadas por reglas de formacion.
Para poder introducir las reglas de formacion de expresiones compuestas en
G OBSTONES vamos a comenzar por profundizar en la idea de tipo presentada en
el subapartado 2.1.4. En su forma mas simple, un tipo puede entenderse como
la descripcion de un conjunto de valores especficos, con propiedades comunes.
En G OBSTONES existen cuatro tipos elementales: los colores, las direcciones, los
booleanos y los numeros.
Se definiran en esta unidad. La nocion de tipo es utilizada, entre otras cosas, para identificar usos erroneos
de un valor, o sea, cuales combinaciones de expresiones estan permitidas al ar-
mar una expresion compuesta, o que comandos pueden armarse con seguridad
para describir acciones. Por ejemplo, la operacion Poner espera que su argumen-
to sea un color. Si Poner recibe un valor de otro tipo, provocara la autodestruccion
del cabezal. La precondicion de Poner es que su argumento sea un valor de tipo
color.

Definicion 3.2.1. Un tipo es la descripcion de un conjunto de valores con ciertas


propiedades comunes. Se utilizan, entre otras cosas, para distinguir entre usos
permitidos y erroneos de una expresion.

Actividad de Programacion 8

Realice el ejercicio 3.2.1.

Ejercicio 3.2.1. Escribir un programa que incluya el comando Poner(17) y com-


probar el error obtenido.

Al presentar la operacion Poner se haba establecido que era una operacion total,
y ahora resulta que la misma es en realidad parcial. Como debe entenderse este
hecho? Lo que sucede es que los errores producidos por utilizar valores de tipo
distinto al esperado (llamados errores de tipo) pueden ser controlados antes de
la ejecucion del programa. De este control se suele decir que impone el uso de
tipos, pues en el caso de que un programa contenga combinaciones erroneas
de tipos en las expresiones es rechazado sin ejecutarlo.
Leer con Atencion

La version actual de G OBSTONES permite invocar definiciones que es-


peran expresiones de un determinado tipo, con expresiones de cualquier
otro tipo, incluso cuando su uso es incorrecto. No obstante, si esto suce-
de el programa fallara al ser ejecutado. Otros lenguajes mas avanzados
imponen restricciones para los tipos de datos, chequeando de alguna
forma en que casos su uso es correcto. Aunque la version actual de
G OBSTONES no controla los errores de tipos de esta manera, no consi-
deraremos como precondicion de los procedimientos y funciones el tipo
de dato que esperamos para los parametros.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


89

Por ejemplo, se dira globalmente que Poner espera un argumento de tipo


color para indicar que fallara con la autodestruccion del cabezal si recibe un valor
de otro tipo, pero no diremos que es precondicion de Poner que el argumento
esperado debe ser de tipo color. Ademas diremos que Poner es una operacion
total a pesar de no serlo realmente.

Para Ampliar

En la herramienta P Y G OBSTONES existe una opcion en la que se verifica,


sin correr el programa, que nuestro codigo no contiene errores de tipos,
y de esa manera asegurar que durante la ejecucion no habra errores de
este estilo. Puede resultar interesante probarla y explorar las ventajas de
utilizarla.

La idea de tipos tambien se aplica a las expresiones. Por ejemplo, la suma solo
es posible realizarla entre numeros. Que sucede si se intenta armar una suma
utilizando un color? Consideremos, por ejemplo, la expresion Verde+1. La misma
no describe a ningun valor. Si se intenta determinar que valor representa esta
expresion, tambien se obtendra la autodestruccion del cabezal.

Ejercicio 3.2.2. Escribir un programa que incluya la expresion Verde+1 y com-


probar el error obtenido.

Leer con Atencion

La suma es tambien una forma de operacion parcial, cuya precondicion


es que sus dos sumandos sean descripciones de numeros, y solo en
ese caso describe a un numero. Esto describe as que la suma espera
dos argumentos de tipo numerico para producir un numero. Al igual que
con el comando Poner, el tipo de los argumentos no se incluira entre las
precondiciones de la suma. De esta manera, diremos que la suma es
una operacion total sobre numeros.

Para Reflexionar

Recuerda la expresion Rojo+Norte que mencionamos al hablar de ti-


pos en la Unidad anterior? Puesto que la suma es una operacion sobre
numeros, esta expresion, de ser ejecutada, producira un error. Que le
parece la idea de contar con una herramienta que verifique que esta
forma de errores no suceda en el programa?

La idea de tipos se aplica tambien a los parametros de un procedimiento. Por


ejemplo, en el procedimiento DibujarLineaHacia, el parametro dir es utilizado
como argumento del comando Mover, y por lo tanto se espera que sea una di-
reccion. Si se invocase al procedimiento con un valor diferente de una direccion,
dicho programa sera erroneo. Para indicar esto, se dira que dir es de tipo direc-
cion, y que Mover solamente espera valores de tipo direccion. De esta manera, la
invocacion DibujarLineaHacia(Rojo) es facilmente identificable como un error,
pues Rojo no es de tipo direccion, sino de tipo color.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


90

Leer con Atencion

En el caso de mas de un parametro en el mismo procedimiento, cada


uno tendra un tipo especfico, y al invocar dicho procedimiento, deberan
suministrarse argumentos de los tipos correctos, en el orden estableci-
do. Por ejemplo, en el procedimiento DibujarLineaDeHacia, el primer
parametro, color, es de tipo color, y el segundo parametro, dir, es de
tipo direccion. Entonces, DibujarLineaDeHacia(Verde, Norte) es una
invocacion correcta del procedimiento, mientras que las inovacaciones
DibujarLineaDeHacia(Norte, Verde) y DibujarLineaHacia(Verde)
no lo son.

La correspondencia entre el tipo de un parametro y el de un argumento es basica,


y solo se la consignara en la precondicion del procedimiento en cuestion estable-
ciendo el tipo que se espera que tenga cada parametro.
A traves del uso de tipos se pueden visualizar rapidamente los usos correc-
tos o erroneos de los diferentes elementos de un lenguaje de programacion, y
muchos lenguajes hacen uso de esta caracterstica. En esta Carpeta usaremos
la terminologa de tipos para guiar la comprension sobre las operaciones que
iremos introduciendo.

3.2.2. Operaciones predefinidas para construir expresiones


Las expresiones compuestas se obtienen a traves de un conjunto de expresio-
nes predefinidas, combinandolas de maneras adecuadas. Las formas adecuadas
quedan determinadas por el tipo de los argumentos y resultados, As, para co-
nocer el conjunto de operaciones predefinidas se puede seguir una clasificacion
de acuerdo con estos tipos. Para conocer un lenguaje de manera completa es
importante conocer cuales son las operaciones predefinidas de cada tipo. A con-
tinuacion presentamos todas las operaciones predefinidas para cada uno de los
cuatro tipos basicos de G OBSTONES, y damos ejemplos de su utilizacion.

Operaciones sobre numeros

El tipo de los numeros trae las operaciones aritmeticas usuales:

la suma, +

la resta, -

la multiplicacion, *

la division entera, div

el resto de la division entera, mod

la exponenciacion, ^

Todas estas operaciones se usan infijas. En el caso de la division entera y el


resto, el comportamiento esperado es que si n div m = q y n mod m = r, entonces
m = q*n + r, y r es positivo y menor estricto que n (en otras palabras, q es el
resultado entero de dividir n por m, y r es el resto de esa division. Estas dos
operaciones son utiles para dividir cuando no se tienen numeros decimales. Con
ellas se pueden definir una cantidad importante de aplicaciones interesantes.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


91

G.3.5. Resultado de ejecutar MostrarNumero(34)

Actividad 9

Realice los siguientes ejercicios. En ellos se busca ejercitar el uso de


expresiones numericas.

Ejercicio 3.2.3. Escribir una expresion sobre numeros que represente la suma
de cuatro veces diez, mas dos. Escribir una expresion sobre numeros que re-
presente la suma de cuatro veces el numero resultante de sumar diez mas dos.
Que diferencias se pueden observar en las expresiones? Y en los resultados?

Ejercicio 3.2.4. Escribir un procedimiento RespuestaVerde que ponga tantas


bolitas verdes como la suma de cuatro veces diez, mas dos, pero sin hacer la
cuenta a mano.
Ayuda: reutilizar el procedimiento PonerN del ejercicio 3.1.2, parte 1 y alguna de
las expresiones del ejercicio anterior.

Ejercicio 3.2.5. Escribir un procedimiento PonerDobleRojas que ponga el doble


de bolitas rojas de lo que dice el parametro.
Ayuda: reutilizar el procedimiento PonerN del ejercicio 3.1.2, parte 1, y combinar-
lo con alguna expresion adecuada que involucre al parametro.

Ejercicio 3.2.6. Escribir un procedimiento MostrarNumero que toma un parame-


tro de tipo numero, y asumiendo que el mismo es menor que 100, lo muestra
en el tablero en dos celdas contiguas utilizando bolitas negras. Para mostrar el
numero, la celda de la derecha debe contener tantas bolitas negras como unida-
des esten representadas por el numero, y la de la izquierda debe contener tantas
bolitas negras como decenas esten representadas por el numero. Por ejemplo, en
el grafico G.3.5 puede observarse el resultado de ejecutar MostrarNumero(34).
Ayuda: para obtener el numero de unidades de un numero se puede utilizar la
operacion de mod con uno de sus argumentos siendo el 10; para obtener el nume-
ro de decenas de un numero menor a 100 se puede utilizar la operacion div con
el argumento 10.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


92

Operaciones sobre colores

Las unicas operaciones especiales de los colores son el calculo de los valores
mnimo y maximo.

el color mnimo en el orden, minColor.

el color maximo en el orden, maxColor.

El valor de minColor() es Azul, y el de maxColor() es Verde.

Operaciones sobre direcciones

El tipo de las direcciones tiene las operaciones de mnima y maxima direccion:

la direccion mnima en el orden, minDir

la direccion maxima en el orden, maxDir

El valor de minDir()es Norte, y el de maxDir()es Oeste.


Para Reflexionar

Estas operaciones por s mismas no parecen muy utiles. La utilidad de


estas operaciones se observa al utilizarlas en conjuncion con coman-
dos avanzados, como la repeticion indexada. Reflexionar sobre el hecho
de que ciertos elementos que por s solos resultan poco interesantes,
cobran sentido al combinarse con otros de formas no triviales. Puede
imaginarse como construir una repeticion indexada que incluya a todos
los colores en el rango que la define?

Las operaciones de mnimo y maximo sobre un tipo dado permiten armar repeti-
ciones indexadas que recorren todos los valores del tipo, sin tener que recordar
el orden particular. Por otra parte, dichos programas expresan con mayor ade-
cuacion el hecho de que se pretende recorrer todos los valores del tipo y no solo
los que posea la version actual del lenguaje. Y siempre es una buena idea que
los programas expresen con mayor precision el proposito del programador.
Actividad de Programacion 10

Realice el ejercicio 3.2.7, y vuelva a considerar la utilidad de las opera-


ciones de mnimo y maximo.

Ejercicio 3.2.7. Reescribir el procedimiento PonerUnaDeCadaColor del ejercicio 2.4.1,


que ponga una bolita de cada color en la celda actual, pero con las siguientes
restricciones:

solo se puede utilizar un unico comando Poner en el cuerpo del procedi-


miento;

no puede nombrarse explcitamente ningun color (o sea, no puede utilizar


ninguna de las siguientes expresiones: Azul, Negro, Rojo ni Verde.)

Ayuda: piense en utilizar una repeticion indexada con expresiones adecuadas


en su rango.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


93

Booleanos y operaciones sobre ellos


El cuarto de los tipos, los booleanos, es un tipo especial, que merece ser consi-
derado detenidamente. Sus valores son usados implcitamente por todos desde
chicos, y son los que expresan la idea de verdad. Cualquier persona distingue
algo verdadero de algo falso. Entonces, as como podemos distinguir una bolita
de color rojo e indicarlo mediante el valor Rojo, o una de color azul e indicar-
lo mediante el color Azul, podremos expresar la capacidad de distinguir entre
verdadero y falso a traves de dos valores: True y False. El valor True describe
la idea de verdadero, mientras que el valor False describe la idea de falso. A
estos dos valores se los conoce como valores de verdad, valores booleanos o
simplemente booleanos.
El tipo de los booleanos trae las operaciones conocidas de logica, a las cuales George Boole fue un matematico
denominamos conectivos logicos (que se explican mas adelante en esta misma y filosofo ingles del siglo XIX que
fundo las bases de la aritmetica de
unidad), y las operaciones de mnimo y maximo booleano: computadoras, y que es considera-
do uno de los padres de la compu-
la negacion, not tacion moderna. La estructura es-
tudiada por este matematico, y que
la conjuncion, && se compone fundamentalmente de
los valores de verdad se conoce co-
la disyuncion, || mo Algebra de Boole.

el booleano mnimo en el orden, minBool


el booleano maximo en el orden, maxBool
La negacion se usa de manera prefija (o sea, la operacion se escribe antes
del operando), y las conjuncion y la disyuncion, infijas (o sea, la operacion se es-
cribe entre medio de los operandos). Es decir, la forma de la operacion not es not
< condicion >, y la forma de la operacion && es < cond1 > && < cond2 >. El signi-
ficado de los conectivos logicos se explica a contiuacion. El valor de minBool()
es False, y el de maxBool() es True.
El uso de expresiones booleanas se ilustrara y ejercitara al trabajar con alter-
nativas.

Operaciones que combinan varios tipos


Hay operaciones que trabajan sobre todos los tipos basicos. Las mas comunes
de estas son las operaciones relacionales, que permiten realizar comparaciones
entre dos elementos del mismo tipo, y cuyo resultado es un booleano (o sea, son
operaciones que provocan la autodestruccion del cabezal si reciben argumentos
de distinto tipo). Ademas hay operaciones que permiten moverse dentro del orden
establecido de cada tipo. Estas operaciones son:
las comparaciones por igualdad:
iguales, ==
diferentes, /=
las comparaciones de orden:
menor, <
menor o igual, <=
mayor, >
mayor o igual, >=
la operaciones de movimiento en el orden:

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


94

calculo del siguiente, siguiente.


calculo del previo, previo.
operaciones especiales solo para algunos tipos:
calculo del opuesto, opuesto o - (unario)
Todas, salvo siguiente, previo y opuesto, se usan de manera infija. Las ope-
raciones de orden siguen una secuencia establecida para cada tipo. El orden de
los numeros es el tradicional, midiendo la cantidad que representa. El orden de
las direcciones es en el sentido de las agujas del reloj, comenzando por el Norte,
el orden de los colores es alfabetico, y el de los booleanos es primero falso y
luego verdadero. La operacion siguiente(< expresion >) devuelve el elemen-
to siguiente en el orden de los elementos del tipo del valor de < expresion >,
volviendo al mnimo en caso de que el elemento sea el maximo. Por ejemplo,
siguiente(2) es 3, siguiente(Norte) es Este, y siguiente(Oeste) es Norte.
La operacion previo(< expresion >) es la operacion inversa, devolviendo el valor
anterior en el orden, y volviendo al maximo en caso de que se trate del mnimo.
Entonces, previo(3) es 2, previo(Oeste) es Sur, y previo(Norte) es Oeste.
La operacion opuesto funciona sobre direcciones o numeros. Se utiliza como
opuesto(< expresion >) o -< expresion >. En el caso de las direcciones trans-
forma Norte en Sur, Este en Oeste, y viceversa. Por ejemplo, el valor de la ex-
presion opuesto(Sur) es Norte y el valor de -Este es Oeste. En el caso de los
numeros, si la expresion vale n, calcula el valor de n.
Ejemplos de uso de estas expresiones son la comparacion de que un cier-
to valor numerico pasado como parametro es menor que un numero fijo (e.g.
num <9), que dos colores pasados como parametros son iguales (e.g. color1 ==
color2) y que la direccion siguiente de una direccion pasada como parametro no
es la ultima posible (e.g. siguiente(dir)maxDir()).
Actividad 11

Realice los ejercicios que se enuncian a continuacion. Los mismos ejem-


plifican el uso de operaciones que combinan varios tipos.

Ejercicio 3.2.8. Escribir una expresion que determine si dos parametros de ti-
po direccion, llamados por ejemplo direccionOriginal y direccionNueva, son
diferentes.
Ejercicio 3.2.9. Escribir una expresion que determine si un numero esta entre 0
y 100. Para ello, combinar dos expresiones relacionales mediante una conjuncion
booleana.

Ejercicio 3.2.10. Escribir un procedimiento ArribaAbajo que tome un parame-


tro de tipo Direccion, y ponga una bolita roja en la celda contigua a la inicial en
la direccion indicada, y una bolita verde en la celda contigua a la inicial, pero en
la direccion opuesta a la indicada. Por ejemplo, el resultado de llamar al procedi-
miento ArribaAbajo(Norte) debera ser como el mostrado en el grafico G.3.6.
Observar que la celda actual al terminar debe ser la misma que la celda inicial.
Ayuda: Como expresar el opuesto de una direccion dada por un parametro?
Pensar en las operaciones recien presentadas. Sugerencia: Definir un procedi-
miento auxiliar con la parametrizacion adecuada para poner una bolita de algun
color en alguna celda contigua. Este procedimiento debera invocarse dos veces
con diferentes argumentos.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


95

G.3.6. Resultado de ejecutar ArribaAbajo(Norte)

Operaciones sobre el tablero

Finalmente, as como el cabezal posee un dispositivo para poner y sacar bolitas,


y para moverse, posee tambien sensores que le permiten saber si hay o no bolitas
de cierto color en la celda actual, cuantas hay, y si puede o no moverse de manera
segura sin caerse del borde del tablero. Todas estas formas se expresan a traves
de expresiones. Las expresiones que tienen que ver con la operatoria del cabezal,
y sirven para determinar ciertos valores asociados a la celda actual son:

hayBolitas(< color >) que dado un color, representa a un booleano que


indica si en la celda actual hay o no bolitas de ese color;

puedeMover(< direccion >) que dada una direccion, representa a un boo-


leano que indica si el cabezal se puede mover en la direccion indicada sin
provocar su autodestruccion;

nroBolitas(< color >) que dado un color, representa al numero de bolitas


de ese color que hay en la celda actual.

Por ejemplo, hayBolitas(Rojo) puede ser True o False, dependiendo del es-
tado de la celda actual: si en la celda hay alguna bolita de color Rojo, enton-
ces esta expresion valdra True; si por el contrario, no hay ninguna, esta expre-
sion valdra False. Si hayBolitas(Rojo) vale False, entonces nroBolitas(Rojo)
valdra 0, y si nroBolitas(Rojo) es distinto de 0, entonces hayBolitas(Rojo)
valdra True. De manera similar a hayBolitas, puedeMover(Sur) valdra True si el
cabezal no se encuentra en la fila de mas abajo, y False si se encuentra en dicha
fila, y de manera analoga para las restantes direcciones. Ejercitaremos el uso
de estas expresiones luego de ver una herramienta nueva para armar comandos
complejos.
Esto completa el repertorio de expresiones de G OBSTONES, con las cuales
se pueden realizar una serie importante de programas.
Actividad 12

Realice el ejercicio 3.2.11. Todava no tenemos suficientes herramientas


para poder aprovechar este ejercicio. Su utilidad se vera en el siguiente
apartado.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


96

Ejercicio 3.2.11. Utilizando algunas de las expresiones recien presentadas, es-


cribir una expresion que determine si la cantidad de bolitas en la celda actual es
menor o igual que un numero determinado (e.g. 9). Recordar que una expresion
para comparar por menor o igual se escribe, por ejemplo, 16 <= 20, y que hay
una expresion para comprobar el numero de bolitas de una celda.

Actividad de Programacion 13

Realice los ejercicios 3.2.12 y 3.2.13 y utilcelos para quitar todas las
bolitas rojas y negras de la celda actual, y la totalidad de las bolitas de
la celda lindante al Norte.

Ejercicio 3.2.12. Escribir un procedimiento SacarTodasLasDeColor que, dado


un parametro color, elimina todas las bolitas del color indicado de la celda ac-
tual. Para realizarlo, considere utilizar el procedimiento SacarN del ejercicio 3.1.2,
parte 3, y combinarlo con alguna de las expresiones recien presentadas.
Ejercicio 3.2.13. Escribir un procedimiento VaciarCelda que elimine todas las
bolitas de la celda actual. Para realizarlo, considere utilizar el procedimiento an-
terior, y una repeticion indexada que recorra todos los colores.

3.2.3. Alternativas condicionales


Los booleanos pueden utilizarse para distinguir entre diferentes alternativas al
momento de describir comandos para el cabezal. Para ello es necesario un co-
mando que, con base en un booleano, decida entre otros dos comandos para
saber cual de ellos debe ejecutarse. Imaginemos que queremos colocar una bo-
lita roja y una negra en una celda solo en el caso de que no haya ninguna roja,
y colocar una negra si hay alguna roja (por ejemplo, porque la bolita roja repre-
senta una flor, y no queremos gastar las flores en nuestra canasta plantando una
donde ya hay, pero queremos colocar fertilizante a todas las flores, incluso las
que ya existen). Ninguna de las herramientas vistas hasta el momento permi-
te describir esta situacion. Entonces presentamos un nuevo comando, llamado
if-then-else:
if (not hayBolitas(Rojo))
-- Verdadero si no hay flores en la celda actual
{
Poner(Rojo) -- Pone una flor, pues no hay ninguna
Poner(Negro) -- Agrega fertilizante
}
else
{ Poner(Negro) } -- Solo agrega fertilizante

Para Reflexionar

Puede mejorar el programa anterior a traves del uso de procedimientos


simples que representen mejor el dominio del problema? (Por ejemplo,
con el procedimiento PonerFlor(), etc.? Que sucedera con la condi-
cion? No podemos utilizar un procedimiento all para darle sentido a la
misma! Es claro que hace falta una forma nueva de nombrar expresio-
nes, la cual se vera en el proximo apartado.

En ingles, if-then-else significa si-entonces-sino, y es la idea de estructura

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


97

alternativa con base en una condicion. Por ejemplo, en este caso, el comando se
leera si no hay una bolita roja (flor) en la celda actual, entonces poner una bolita
roja (flor) y una negra (fertilizante), y si ya hay flores, poner solo una bolita negra
(fertilizante).
La forma general del comando if-then-else esta dada por la siguiente defi-
nicion:
Definicion 3.2.2. El comando de alternativa condicional (o simplemente condi-
cional) if-then-else tiene la siguiente forma:
if (< bool >)
< unBloque >
else
< otroBloque >
siendo < bool > una expresion que describe un valor de verdad (booleano), y
donde los bloques < unBloque > y < otroBloque > son bloques de codigo cua-
lesquiera (que normalmente son diferentes, aunque podran ser iguales). Al blo-
que < unBloque > se lo denomina rama verdadera (o rama del then) y al bloque
< otroBloque > se lo denomina rama falsa (o rama del else).
El comando if-then-else describe la decision de realizar la accion descrita por
el bloque < unBloque >, en caso que la condicion sea True, o de realizar la accion
descrita por < otroBloque > en caso que la condicion sea False. Observar que
los parentesis son necesarios siempre alrededor de la condicion.
Actividad de Programacion 14

Realice el ejercicio 3.2.14. Considere la cantidad de trabajo necesario, y


reflexione sobre la importancia de reutilizar codigo definido con anterio-
ridad (segun se sugiere en dicho ejercicio).

Ejercicio 3.2.14. Supongamos que una celda representa un dgito de un indica-


dor de kilometraje, para lo cual utiliza bolitas negras. Escribir un procedimiento Un dgito es un numero entre 0 y 9.
IncrementarDigCuentaKm(), que incremente en uno el kilometraje indicado por
ese dgito (y solo ese). Tener en cuenta que el indicador, al llegar al lmite de
9 debe volver a 0, pues es un dgito. Considerar el uso de una alternativa pa-
ra detectar las dos situaciones posibles (cuales son?), y la reutilizacion de la
condicion del ejercicio 3.2.11 y del procedimiento del ejercicio 3.2.12.

Una variante util del comando if-then-else es cuando no existe una accion
alternativa para la rama del else. En ese caso, la alternativa se transforma real-
mente en un comando condicional (o sea, un comando que solo se ejecuta si se
cumple cierta condicion). Esto es extremadamente util para evitar que una opera-
cion parcial provoque la autodestruccion del cabezal. Para ello, basta con utilizar
como condicion del if-then-else una expresion < condicion > que valga True
cuando la precondicion de la operacion dada en la rama del then sea valida. Por
ejemplo, si se quiere sacar una bolita, puede preguntarse primero si la misma
existe, de la siguiente manera:
if (hayBolitas(Rojo)) { Sacar(Rojo) }
Notar que la precondicion de Sacar(Rojo) es que haya bolitas rojas, y la condi-
cion del if-then es una expresion que vale True siempre que haya bolitas rojas;

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


98

o sea, la condicion del if-then garantiza la precondicion de la rama del then.


De esta manera, la operacion dada por la alternativa condicional es total incluso
aunque el cuerpo de la misma es parcial, pues el comando Sacar solamente se
invocara cuando haya una bolita roja en la celda actual; en caso de que no haya
ninguna bolita roja, este comando compuesto no tendra ningun efecto.
Ejercicio 3.2.15. Escribir un procedimiento QuitarHastaTresFlores que, supo-
niendo que en la celda actual hay entre cero y tres flores representadas cada
una por una bolita roja (pero no se sabe cuantas exactamente), las elimine de
la celda. El procedimiento debe describir una operacion total. Utilizar nombres
adecuados para la subtarea de quitar una flor (pero no puede hacerse aun con la
condicion).
Ayuda: utilizar la variante de alternativa dada por el comando if-then.
Esta forma de evitar la parcialidad de ciertas operaciones debe usarse con cuida-
do. Hay ocasiones donde es mejor utilizar la operacion directamente, y asumir el
requisito de que la precondicion debe cumplirse trasladandolo al procedimiento
que se esta definiendo (por ejemplo, cuando la condicion es demasiado com-
pleja, o no queremos realizar la verificacion). Por ejemplo, si consideramos la
operacion MoverN(n,dir) del ejercicio 3.1.2, parte 2, vemos que la misma tiene
como precondicion que haya tantas celdas en la direccion dir como la cantidad
indicada por n. Esto garantiza que la operacion se mueve exactamente n lugares
o falla. Si en cambio hubieramos realizado la variante donde el Mover interno se
utilizaba de manera segura, la operacion hubiese quedado total pero no habra
garantas de que se movio n lugares (ver el ejercicio 3.2.16).
Actividad 15

Realice el ejercicio 3.2.16 y compare su comportamiento con el procedi-


miento MoverN del ejercicio 3.1.2, parte 2.

Ejercicio 3.2.16. Realizar un procedimiento MoverNTotal que dados un parame-


tro n de tipo numero y uno dir de tipo direccion, se mueva n celdas en la direccion
dir, si puede, o quede detenido en el borde, si hay menos de n celdas en dicha
direccion.
En la Unidad siguiente volveremos sobre la alternativa condicional para pro-
fundizarla, y sobre otras formas avanzadas de comandos.

3.2.4. Funciones simples


As como un procedimiento es una forma de dar nombre a un grupo de coman-
dos, existe un mecanismo para darle nombre a un grupo de expresiones. Tal
mecanismo es conocido con el nombre de funcion. Una funcion simple es basi-
camente otra forma de nombrar a una expresion compuesta.
Definicion 3.2.3. Una funcion simple es una forma de asignar un nombre a una
expresion. La forma de definir una funcion simple en G OBSTONES es
function < funcName >()
{
return(< expresion >)
}
siendo < funName > un identificador que comienza con minuscula y < expresion >,
una expresion de cualquier tipo basico.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


99

La operacion de return de la declaracion de una funcion indica la expresion que


la misma representa.
Leer con Atencion

Las funciones se pueden invocar de manera similar a un procedimiento


con la diferencia de que, como representan a un valor, deben utilizar-
se como cualquier expresion (y no como un comando). Por ejemplo, un
llamado de funcion puede ser usado como argumento, o combinado en
expresiones complejas, etcetera.

Definicion 3.2.4. Una funcion simple puede ser usada como una expresion. La
forma de invocarla es escribir su nombre seguida por parentesis, de la siguiente
manera
< funcName >()
donde < funcName > es el nombre de alguna funcion declarada en el programa.

Un ejemplo sencillo de funcion simple es la que calcula el numero total de


bolitas de la celda actual.
function nroBolitasTotal()
{- PROPOSITO:
* calcula el total de bolitas de la celda actual
PRECONDICION:
* ninguna, es una operacion total
-}
{
return ( nroBolitas(Azul) + nroBolitas(Negro)
+ nroBolitas(Rojo) + nroBolitas(Verde)
)
}
Al utilizar esta funcion, el valor representado por su invocacion es el numero total
de bolitas de todos los colores en la celda actual.
Por ejemplo, supongamos que un grupo de bolitas de varios colores represen-
ta a algun elemento de un juego, y que queremos representar su sombra en la
celda vecina al Este. Vamos a representar la sombra por una cantidad de bolitas
negras igual a la cantidad total de bolitas del elemento. El procedimiento para
hacer la sombra podra ser el siguiente
procedure HacerSombra()
{- PROPOSITO:
* ilustrar el uso de funciones
* pone una sombra del elemento representado en la celda
actual, en la celda lindante al Este
PRECONDICION:
* que haya una celda al Este
OBSERVACION:
* esta es una manera adecuada de abstraer este problema
-}
{
DibujarSombra(nroBolitasTotal())
-- usa una funcion para calcular el numero de bolitas de
-- la celda actual y llama a DibujarSombra tal numero

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


100

-- como argumento
}

donde DibujarSombra es un procedimiento que recibe un parametro numerico y


coloca esa cantidad de bolitas negras en la celda lindante al Este, volviendo a la
celda original antes de terminar.

Ejercicio 3.2.17. Escribir el procedimiento DibujarSombra que recibe un parame-


tro valorIntensidad y coloca una sombra de la intensidad dada por el parametro
en la celda lindante al Este, retornando luego a la celda original.

Las funciones simples permiten abstraer la implementacion efectiva de ciertas


En este caso, llevar mas cerca ideas expresadas mediante expresiones compuestas. Quizas las expresiones
de las ideas del programador a que resulten mas util abstraer de esta manera sean las determinadas por con-
traves de nombrar adecuadamente
los elementos.
diciones complejas expresadas mediante la combinacion de varias expresiones
booleanas simples mediante conectivos logicos.

Condiciones booleanas

A partir de los valores de verdad basicos pueden construirse condiciones com-


plejas a traves del uso de conectivos logicos. Los conectivos logicos son ope-
raciones entre booleanos. Los mas comunes, y que pueden ser representados
directamente en G OBSTONES, son la negacion, la conjuncion y la disyuncion.

Definicion 3.2.5. Un conectivo logico es una operacion entre booleanos. Los


conectivos mas comunes son la negacion, la conjuncion y la disyuncion.

La negacion es un conectivo que toma un booleano y devuelve otro booleano.


Transforma True en Falsey viceversa. La manera de escribir la negacion de una
expresion booleana es con la operacion not. En resumen, not True es igual a
False, y not False es igual a True.

Definicion 3.2.6. La negacion es un conectivo logico unario. Su forma general


es

not < expBooleana >

donde < expBooleana > es cualquier expresion cuyo resultado sea True o False.

Con esta operacion, por ejemplo, podra escribirse una condicion que verifique
si en la celda actual no hay bolitas rojas como: not hayBolitas(Rojo). Esta
expresion valdra True cuando el numero de bolitas rojas en la celda actual sea
0, y False en caso contrario, extactamente lo opuesto a hayBolitas(Rojo).

Ejercicio 3.2.18. Escribir una funcion noHayMarcianos() que retorne verdadero


si en la celda actual no hay ningun marciano, y falso en caso de que haya alguno.
Un marciano se representa mediante una bolita de color Azul.

Ejercicio 3.2.19. Escribir un ejercicio celdaVacia() que retorna verdadero si en


la celda actual no hay ninguna bolita de ningun color, y falso en caso de que haya
alguna. Para realizarlo, reutilizar la funcion nroBolitasTotal, y combinarla con
un operador de igualdad y el conectivo logico de negacion.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


101

Leer con Atencion

Otro conectivo logico importante es la conjuncion, que toma dos valo-


res de verdad y retorna un tercero. La conjuncion de dos proposiciones,
expresada mediante la operacion infija &&, sera verdadera cuando am-
bas lo sean, y falsa en otro caso. Es la manera de representar el y del
lenguaje natural.

Definicion 3.2.7. La conjuncion es un conectivo logico binario. Su forma general


es
< expBooleana1 > && < expBooleana2 >
donde < expBooleana1 > y < expBooleana2 > son expresiones cuyo resultado es
True o False.

La expresion True && True tendra como resultado True, y las expresiones True
&& False, False && True y False && False tendran como resultado False. De
esta manera se pueden construir condiciones complejas, como preguntar si en
la celda actual hay bolitas rojas y verdes al mismo tiempo: hayBolitas(Rojo) &&
hayBolitas(Verde).
Ejercicio 3.2.20. Escribir una funcion hayFlores() que retorne verdadero si en
la celda actual hay alguna flor, y falso en caso de que no haya ninguna. Una flor se
representa mediante una bolita de color Rojo y una de color Verde. La condicion
de que haya flores puede verificarse, por tanto, verificando que haya bolitas de
ambos colores en la celda. Observar que no se pide verificar que la cantidad de
bolitas verdes y rojas coincida, sino solo que haya de ambas! Y tambien que no
molesta que haya bolitas de otros colores.

Ejercicio 3.2.21. Escribir una funcion floresSinMarcianos() que retorne ver-


dadero si en la celda actual hay alguna flor, pero no hay ningun marciano. Con-
sidere reutilizar las funciones de los ejercicios anteriores, combinadas mediante
algun conectivo adecuado.

Ejercicio 3.2.22. Escribir una funcion hayExactamenteUnaFlor() que retorna ver-


dadero si en la celda actual hay exactamente una flor (representada igual que en
el ejercicio 3.2.20). Tener en cuenta que no puede haber mas de una bolita ro-
ja y una verde en la celda. Como se puede expresar esta condicion utilizando
conjunciones y operaciones relacionales?

El tercer conectivo logico que se puede escribir en G OBSTONES de manera primi-


tiva es la disyuncion. La disyuncion toma dos valores de verdad y retorna otro. La
disyuncion es verdadera cuando al menos uno de los argumentos es verdadero,
siendo falsa solo si ambos son falsos. Para denotarla se utiliza la operacion infija
, || de la siguiente manera:
Definicion 3.2.8. La disyuncion es un conectivo logico binario. Su forma general
es
< expBooleana1 > || < expBooleana2 >
donde < expBooleana1 > y < expBooleana2 > son expresiones cuyo resultado es
True o False.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


102

Las expresiones True || True, True || False y False || True tendran como
resultado True, y la expresion False || False tendra como resultado False.
Con la disyuncion se puede pregunta si en la celda actual hay bolitas rojas o
hay bolitas verdes (puede faltar cualquiera de las dos): hayBolitas(Azul) ||
hayBolitas(Negro).
Actividad 16

Como construir una condicion que verifique si hay alguna bolita en la


celda actual? Considere el ejercicio 3.2.23.

Ejercicio 3.2.23. Escribir una funcion hayBolitas que retorne verdadero si hay
alguna bolita en la celda actual (no importa su color). Considerar la utilizacion de
una combinacion mas complicada de hayBolitas y ||, y que involucre a los 4
colores. Puede expresar la condicion de alguna otra forma?
Ejercicio 3.2.24. Escribir un procedimiento PintarCeldaMarron que pinte una
celda de color marron (agregando bolitas de los cuatro colores en la celda actual)
solo si no hay bolitas de ningun color. Considerar la utilizacion de la funcion del
ejercicio anterior y una alternativa condicional.

Para Reflexionar

Esta forma de expresiones complicadas puede ser extremadamente en-


gorrosa si tuvieramos que usarlas directamente. Entiende la importan-
cia de la habilidad de nombrar sus ideas? Este proceso, al que deno-
minamos abstraccion es sumamente importante en toda actividad de
programacion.

Leer con Atencion

Al combinar diferentes conectivos logicos, la negacion se resuelve pri-


mero, luego la conjuncion, y finalmente la disyuncion. Esto se denomina
precedencia de los operadores logicos.

Definicion 3.2.9. La precedencia de un operador es la prioridad que tiene el


mismo en una expresion combinada para ser resuelto.
La negacion tiene mas precedencia que la conjuncion, y la conjuncion mas prece-
dencia que la disyuncion. En caso de precisar alterar este orden, deben utilizarse
parentesis. Entonces, la expresion
not hayPasto() && not hayMarciano() || haySangre()
significa lo mismo que
((not hayPasto()) && (not hayMaciano()))
|| haySangre()
Para obtener otros resultados, deben utilizarse parentesis de manera obligatoria.
Como ser
not (hayPasto()
&& (not (hayMarciano() || haySangre()))
)

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


103

Considerar que las funciones hayPasto(), hayMarciano() y haySangre() veri-


fican la existencia de cada uno de estos elementos, representados respectiva-
mente mediante bolitas verdes, azules y rojas.
Ejercicio 3.2.25. Escribir hayPasto(), hayMarciano() y haySangre().

Actividad 17

Cual sera el valor de verdad de las distintas condiciones compuestas


dadas antes? Para determinarlo, escriba una tabla que consigne las dife-
rentes posibilidades de una celda para contener bolitas (por ejemplo, si
contiene bolitas verdes pero no azules ni rojas, si contiene bolitas verdes
y azules pero no rojas, etc., e indicar en cada caso el valor booleano de
las expresiones.) Que diferencia se observa entre ambas condiciones
(con diferentes precedencias)?

Ejercicio 3.2.26. Escribir un procedimiento PlantarYFertilizar que, reutilizan-


do la idea del ejemplo al comienzo del subapartado 3.2.3, plante una flor si no
hay ninguna, y fertilice las flores que haya (ya sea que fueron recien colocadas o
ya existan). Nombre adecuadamente sus subtareas utilizando procedimientos y
funciones auxiliares de manera conveniente.
Ejercicio 3.2.27. Revisar el ejercicio 3.2.14 para abstraer de manera adecuada
la condicion utilizada, dandole un nombre representativo a la misma mediante
una funcion (por ejemplo, seVaAExceder()).

3.3. Funciones avanzadas


En el apartado anterior aprendimos como escribir y utilizar funciones simples
(definicion 2.2.9), y trabajamos con ellas, aprendiendo como valernos adecuada-
mente para abstraer nuestras ideas. En este apartado vamos a extender nuestra
concepcion sobre las funciones, exhibiendo su uso junto con otros conceptos
avanzados de programacion.

3.3.1. Funciones con parametros


As como los procedimientos simples pueden generalizarse a esquemas de pro-
cedimientos mediante el uso de parametros, las funciones simples pueden ge-
neralizarse a esquemas de funciones mediante el mismo recurso. La idea es la
misma: un parametro indica el nombre de un valor que cambia en cada uso de
la funcion (como vimos, similar a un agujero que debe completarse al invocar
su uso en el codigo). La sintaxis utilizada es similar a la utilizada para los proce-
dimientos: el nombre de los parametros de la funcion se coloca entre parentesis
despues del nombre de la misma (indicando que esta funcion tiene dichos agu-
jeros).
Definicion 3.3.1. Una funcion con parametros es similar a una funcion simple,
pero agregando la nocion de parametros. La forma de definir una funcion con
parametros en G OBSTONES es
function < funcName >(< params >)
{
return(< expresion >)
}

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


104

siendo < funName > un identificador que comienza con minuscula, < params >,
una lista de identificadores que comienzan con minusculas y < expresion >, una
expresion de cualquier tipo basico.
Las funciones con parametros se pueden invocar de manera similar a la vista
para procedimientos con parametros, mediante el uso de argumentos, con la
diferencia, ya mencionada, de que por ser expresiones solo se pueden utilizar en
lugares donde se espera una expresion.
Definicion 3.3.2. Una funcion con parametros puede ser usada como una ex-
presion. La forma de invocarla es escribir su nombre seguida por argumentos, de
la siguiente manera
< funcName >(< args >)
donde < args > es una lista de valores especficos (los argumentos) para los
parametros de la funcion.
Las nociones de concordancia de tipos entre cada argumento y los usos que se
les da a los parametros correspondientes es similar a la vista para los procedi-
mientos.
Por ejemplo, podemos ver si hay mas bolitas de un color que de otro, pero
usando parametros para indicar que colores queremos.
function hayMasQue(color1, color2)
{-
PROPOSITO:
* retorna verdadero si hay mas bolitas del color1
que bolitas del color2 en la celda actual
PRECONDICION:
* Ninguna (es una funcion total)
-}
{
return (nroBolitas(color1) > nroBolitas(color2))
}
Con esta funcion podra verificarse que hubiera mas bolitas rojas que verdes
y mas negras que azules mediante la expresion hayMasQue(Rojo,Verde) &&
hayMasQue(Azul,Negro).
Actividad de Programacion 18

Realice el ejercicio 3.3.1. Codifico un procedimiento auxiliar para abs-


trear la forma de huir? O utilizo simplemente un comando basico?

Ejercicio 3.3.1. Escribir un procedimiento HuirSiPintaMal que huya de la celda


actual moviendose al Norte si en la misma hay mas enemigos que aliados. Los
aliados se representan mediante bolitas verdes y los enemigos mediante bolitas
rojas. Considerar la reutilizacion de la funcion hayMasQue, pero utilizando fun-
ciones adecuadas para abstraer la representacion de aliados y enemigos (por
ejemplo, con las funciones colorAliado y colorEnemigo).

Actividad de Programacion 19

Realice el ejercicio 3.3.2. Utilcelo en una funcion esValorDigito que


dado un numero determine si es un dgito o no, retornando un booleano.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


105

Ejercicio 3.3.2. Escribir una funcion enIntervalo que dados un numero n y dos
numeros inf y sup, retorne verdadero si n esta dentro del intervalo [inf,sup] (o
sea, es mayor o igual a inf y menor o igual a sup).

Las funciones parametrizadas proveen una herramienta mas poderosa que


las funciones simples. Sin embargo, el verdadero poder de las funciones radi-
ca en poder realizar alguna forma de procesamiento antes de retornar su valor,
permitiendo, por ejemplo, visitar otras zonas del tablero.

3.3.2. Funciones con procesamiento


Las funciones simples y parametrizadas son una forma importante de abstraer
ideas que se expresan mediante expresiones complejas. Sin embargo, para po-
der devolver valores que dependan de otras celdas que no sea la celda actual,
o expresar valores que dependan de procesar informacion dispersa en el table-
ro, es preciso contar con una forma mas poderosa de funciones: las funciones
con procesamiento. Este procesamiento se consigue agregando a las funciones,
previo a expresar su valor de retorno, un grupo de comandos que realicen este
procesamiento.

Definicion 3.3.3. Una funcion con procesamiento es una forma de funcion que
ademas de nombrar a una expresion, realiza previamente algun procesamiento.
La forma de definir una funcion con procesamiento en G OBSTONES es

function < funcName >(< params >)


{
< comando >
return(< expresion >)
}

siendo < funName >, < params > y < expresion > como antes, y < comando >
un comando (que puede ser un comando compuesto como una secuencia de
comandos.

Por ejemplo, si queremos expresar la cantidad de enemigos (representados como


antes por una bolita roja cada uno) en una celda lindante a la actual, podemos
utilizar la siguiente funcion

function nroEnemigosAl(dir)
{-
PROPOSITO:
* retorna la cantidad de enemigos en la celda lindante a la
actual en la direccion dir
PRECONDICION:
* hay una celda lindante en direccion dir
-}
{
Mover(dir)
return(nroBolitas(colorEnemigo()))
}

La invocacion de una funcion con procesamiento es exactamente la misma que


la de una funcion con parametros. La unica diferencia es que, en G OBSTONES,
el procesamiento que la misma realiza no se lleva a cabo de manera real sobre
el tablero, sino solo de una forma simulada. Por eso, al retornar de una funcion
con procesamiento, el estado del tablero no vario absolutamente en nada. Esto

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


106

permite utilizar las funciones con procesamiento para retornar informacion, pero
sin tener que preocuparse por las consecuencias del procesamiento.
Leer con Atencion

Esta caracterstica de G OBSTONES es unica. Las funciones son expre-


siones y como tales, no deben denotar acciones (o sea, producir efectos)
sino denotar valores. Por eso, el procesamiento se realiza de manera si-
mulada. Sin embargo, en casi todos los demas lenguajes, se permite que
las funciones ademas de denotar un valor, produzcan efectos. Tecnica-
mente deberamos decir que no son funciones, sino procedimientos que
retornan valores; pero es tan comun utilizar el nombre de funcion para
este tipo de procedimientos que es importante estar atentos a las dife-
rencias, ya que la forma de pensar las funciones cambia!

Por ejemplo, imaginemos una situacion donde queremos agregar en la celda ac-
tual un numero de aliados igual a la cantidad de enemigos en la celda al Norte,
mas uno (por ejemplo, como parte de un programa que expresa nuestra estrate-
gia de defensa en un juego), suponiendo la misma codificacion que vimos antes
(un enemigo se representa con una bolita roja y un aliado con una bolita verde).
El procedimiento podra ser:
procedure EstrategiaDeDefensa()
{-
PROPOSITO:
* agregar tantos aliados en la celda actual como
enemigos hay en la celda lindante al Norte,
mas uno (si hay enemigos)
PRECONDICION:
* hay una celda lindante al Norte
-}
{
if (hayEnemigosAl(Norte))
{ AgregarAliados(nroEnemigosAl(Norte)+1) }
}
Observar que si bien la funcion nroEnemigosAl realiza un movimiento para retor-
nar la cantidad de enemigos en la direccion dada, este movimiento no es refleja-
do por el procedimiento EstrategiaDeDefensa, que solo agrega los aliados en la
celda actual.
Actividad de Programacion 20

Realice los ejercicios 3.3.3 y 3.3.4, con el fin de completar el procedi-


miento anterior. Pruebe todos estos elementos en un programa sencillo
y verifique que efectivamente las funciones no producen ningun efecto.

Ejercicio 3.3.3. Escribir la funcion hayEnemigosAl que determina si hay enemi-


gos en la celda lindante en la direccion dada. Cual es la precondicion de la
funcion?
Ejercicio 3.3.4. Escribir el procedimiento AgregarAliados que agrega tantos alia-
dos como el numero indicado como parametro.
Un procesamiento mas complicado puede lograrse mediante el uso de co-
mandos mas complejos, combinados con la idea de usar bolitas de algun color

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


107

para indicar resultados de exito.


Por ejemplo, la siguiente funcion verifica si hay enemigos en alguna de las 3
celdas lindantes al Norte (supone el uso de una funcion hayEnemigosAlEnRango,
similar a la funcion hayEnemigosAl vista, pero agregando un parametro numerico
para indicar el rango exacto donde deben buscarse enemigos).

function hayEnemigosCercaAlNorte()
{-
PROPOSITO:
* retorna verdadero si hay algun enemigo en las
proximas 3 celdas al Norte de la actual
PRECONDICION:
* hay 3 celdas lindantes al Norte
-}
{
SacarTodas(Azul) -- Elimina todas las bolitas azules,
-- para estar seguro que no hay ninguna
repeatWith i in 1..3
{ if(hayEnemigosAlEnRango(Norte, i))
{ Poner(Azul) } -- Agrega una azul si hay enemigos
}
return(hayBolitas(Azul)) -- Si hay azules, es porque
-- uno de los rangos dio verdadero
}

Observar que se utilizan bolitas azules para indicar el exito de la busqueda. Pues-
to que el procesamiento realizado por la funcion es solo simulado y no real, esta
modificacion de las bolitas azules no sera reflejada en el procedimiento que uti-
lice a hayEnemigosCercaAlNorte. En este ejemplo particular, la funcion podra
haberse escrito simplemente como

function hayEnemigosCercaAl()
{-
PROPOSITO:
* retorna verdadero si hay algun enemigo en las
proximas 3 celdas al Norte de la actual
PRECONDICION:
* hay 3 celdas lindantes al Norte
-}
{
return(hayEnemigosAlEnRango(Norte,1) ||
hayEnemigosAlEnRango(Norte,2) ||
hayEnemigosAlEnRango(Norte,3)
}

Sin embargo, esta forma no sera parametrizable en cuanto a la distancia a me-


dir, quitando poder de generalidad a la solucion propuesta y haciendolo menos
modificable a futuro. Por ejemplo, si modificasemos la definicion de cerca pa-
ra contemplar 10 celdas en lugar de 3, el resultado habra sido mas engorroso.
O si hubieramos considerado agregar un parametro numerico que estableciese
el rango en el que nuestros exploradores pueden detectar enemigos, no habra
sido posible expresar la funcion como una disyuncion compleja, puesto que no
sabramos de antemano cuantos llamados debemos realizar.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


108

Actividad de Programacion 21

Realice los ejercicios 3.3.5 y 3.3.6 y pruebelos en algun programa.

Ejercicio 3.3.5. Escribir una funcion hayEnemigosAlEnRango que, dado un para-


metro d de tipo direccion y uno n de tipo numero indique si hay enemigos en la
celda distante exactamente n celdas en direccion d a partir de la celda actual.
Utilizar la idea de la funcion hayEnemigosAl del ejercicio 3.3.3 pero utilizando el
procedimiento MoverN en lugar del comando Mover.
Ejercicio 3.3.6. Escribir una funcion hayEnemigosCercaNAlNorte que, dado un
parametro n de tipo numero indique si hay enemigos en alguna de las n celdas
contiguas al Norte. Utilizar la idea de procesar con una repeticion indexada y
bolitas para indicar el resultado.

El procesamiento que es posible realizar en las funciones con procesamiento


se vera potenciado al incorporar formas de recordar valores. Esto se realizara en
la siguiente unidad.

3.4. Ejercitacion
En este apartado se enuncia una serie de ejercicios adicionales a los ya dados.
Al igual que en ejercitaciones previas, para su correcta resolucion son necesarios
todos los elementos aprendidos en los apartados y unidades anteriores.
Actividad de Programacion 22

Realice los ejercicios enunciados en este apartado. Nuevamente, le re-


cordamos que debe utilizar todas las buenas practicas que venimos es-
tudiando.

Ejercicio 3.4.1. Escribir una funcion nroBolitasNAl, que dados un color c, un


numero n y una direccion d, determine el numero de bolitas de color c en la celda
distante exactamente n lugares en direccion d a partir de la celda actual. Utilizar
como inspiracion la funcion hayEnemigosAlEnRango del ejercicio 3.3.5.
El siguiente ejercicio se basa en una idea de Pablo Tobia. Gracias Pablo!
Ejercicio 3.4.2. En este ejercicio utilizaremos el display de un ecualizador repre-
sentado en el tablero. El ecualizador tiene 2 canales (izquierdo y derecho) con 3
frecuencias cada uno (agudos, medios y graves). Cada frecuencia de cada canal
posee 4 leds verdes y 2 leds rojos. Para representar el display en el tablero se
utiliza una columna por cada frecuencia de cada canal (6 en total), a partir de la
columna mas al Oeste. Cada frecuencia se representa desde la celda base (la
mas al Sur), dejando dicha celda libre, y ubicando un led por celda hacia arriba.
Los leds encendidos se representan mediante una bolita del color correspon-
diente en la celda, y los apagados con una celda vaca. Se muestra un tablero
representando al display de un ecualizador en el grafico G.3.7a.
Escribir un procedimiento CalcularIntensidades, que dado un tablero con-
teniendo la representacion de un display de ecualizador cuente la intensidad de
cada frecuencia, registrando el resultado en la celda de la base de cada columna

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


109

(a). Tablero inicial representando el dis- (b). Tablero final representando el ecuali-
play de un ecualizador. zador con intensidades.

G.3.7. Tablero representando el display de un ecualizador (antes y despues de


calcular las intensidades)

con bolitas azules si la intensidad es menor o igual que 4, y negras si es mayor. El


resultado para el ecualizador dado como ejemplo se muestra en el grafico G.3.7b.

Para realizar el ejercicio anterior, se recomienda dividir en subtareas y utilizar


funciones y procedimientos segun lo visto hasta el momento. Puede resultar util
contar con algunos de los nombres de los procedimientos y funciones en cues-
tion: TotalizarFrecuenciaActual, ProcesarLedsVerdes, ProcesarLedsRojos,
NormalizarColorIntensidad y nroBolitasNAl. Tenga en cuenta que para to-
talizar todas las frecuencias puede usar una repeticion indexada, y para totalizar
la frecuencia actual puede utilizar la idea de hayEnemigosCercaAlNorte.

Los siguientes ejercicios se basan en una idea de Pablo Barenbaum. Utilizan su


idea y su enunciado para un juego inspirado en el ajedrez, que el denomino Pro-
cedrez. Primero se describira el juego, y luego se enunciaran los ejercicios que
ayudaran a ir resolviendo distintos aspectos del juego de manera incremental.
Gracias Pablo!
El Procedrez es un juego en el que intervienen dos jugadores, que mueven
piezas en un tablero de tamano variable, dividido en escaques o casillas. Las
piezas pueden ser de tres clases diferentes: visir, torre y rey. Un jugador puede
tener varios visires y varias torres, pero solo un rey. Las piezas se mueven de la
siguiente manera, de manera similar a los movimientos que se pueden encontrar
en el ajedrez:

Los visires y el rey se mueven una casilla en cualquier direccion, ortogonal


o diagonal.

Las torres se mueven en lnea recta cualquier numero de casillas, pero solo
en direccion ortogonal. Las torres no pueden saltar las propias piezas ni
las piezas enemigas.

Ademas, si una pieza se mueve sobre una casilla ocupada por una pieza del opo-
nente, captura a dicha pieza, que se retira permanentemente del tablero, exacta-
mente como en ajedrez.
Tambien como en el ajedrez, se dice que el rey de un jugador esta en jaque
si puede ser capturado por una pieza del oponente. El objetivo del juego es dar

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


110

jaque mate, que consiste en dar jaque al rey del oponente, de tal manera que le
resulte imposible evitar el jaque.
El tablero del juego se representara con el tablero de G OBSTONES. Las piezas
del primer jugador se representaran con bolitas de color Rojo y las del segundo
con Negro; el numero de bolitas dependera de la clase de pieza en cuestion
(1 = visir, 2 = torre, 3 = rey). Las bolitas de color Verde y Azul se reservaran para
marcar posiciones del tablero.
Ejercicio 3.4.3. Implementar las siguientes funciones auxiliares que se usaran
en el resto de los ejercicios del Procedrez.
visir() que devuelve 1.
torre() que devuelve 2.
rey() que devuelve 3.
hayPieza() que devuelve True si hay una pieza en la casilla actual.
clasePieza() que devuelve la clase de la pieza en la casilla actual, asu-
miendo que hay una.
colorPieza() que devuelve el color de la pieza en la casilla actual, asu-
miendo que hay una.
marcadaComoDestino() que devuelve True si la casilla actual esta marcada
como destino (con una bolita Azul).
marcadaComoMovimiento() que devuelve True si la casilla actual esta mar-
cada como movimiento (con alguna bolita Verde).

Este ejercicio simplemente prepara algunas funciones que resultaran utiles en


el resto de los ejercicios. La idea de proponerlos es guiar en la forma de pen-
sar como abstraer la representacion de piezas de manera de poder pensar en
terminos del problema y no de la representacion.
Ejercicio 3.4.4. Implementar el procedimiento MarcarMovimientosVisir que re-
cibe un color col y marca con una bolita de ese color cada uno de los potenciales
movimientos del visir o el rey ubicado en la casilla actual. La precondicion del pro-
cedimiento es que debe haber un visir o un rey en la casilla actual.
Deben marcarse las casillas ocupadas por piezas del oponente, ya que estos
son movimientos validos (capturas). No deben marcarse las casillas que esten
ocupadas por piezas del mismo color, ya que dos piezas no pueden ocupar la
misma casilla simultaneamente.
El cabezal debe quedar ubicado en la casilla en la que estaba originalmente.

Algunos ejemplos de posibilidades de este ejercicio se muestran en los grafi-


cos G.3.8 y G.3.9.
Ejercicio 3.4.5. Suponiendo que ya estan definidos MarcarMovimientosVisir y
MarcarMovimientosTorre, procedimientos que marquen los movimientos de las
piezas de manera similar a lo realizado en el ejercicio anterior, implementar el
procedimiento MarcarMovimientosPieza que recibe un color col y marca con
una bolita de ese color cada uno de los potenciales movimientos de la pieza
ubicada en la casilla actual (cualquiera sea esta pieza).
La precondicion es que debe haber una pieza en la casilla actual.

Continuaremos con operaciones del Procedrez en la proxima Unidad, luego de


aprender algunas herramientas avanzadas nuevas.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


111

G.3.8. Los visires y el rey pueden moverse libremente

G.3.9. El rey negro puede capturar a la torre roja pero no puede pasar sobre su
propia torre

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


112

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


113

Alternativa, repeticion y memoria

En esta Unidad vamos a profundizar las herramientas de alternativa y repeticion


que vimos en la Unidad anterior, mostrando otras formas posibles, y discutiendo
las consecuencias de poseerlas. Ademas presentaremos la nocion de memoria,
como una forma de recordar valores a lo largo de la ejecucion de un programa.
Si bien la memoria no es imprescindible para solucionar problemas (con pa-
rametrizacion se pueden lograr los mismos efectos), es una herramienta que per-
mite expresar muchos problemas de una forma mas concisa, y es ampliamente
utilizada en la mayora de los lenguajes de programacion. Sin embargo, su co-
rrecta utilizacion conlleva un numero importante de dificultades que la hacen ex-
tremadamente compleja de manejar. Puesto que el proposito de esta Carpeta es
brindar un panorama sobre la programacion, no abundaremos ni en los proble-
mas que puede ocasionar su uso, ni en la multitud de soluciones propuestas y
sus consecuencias.
Ademas de las herramientas basicas de los lenguajes, presentaremos una
herramienta abstracta para organizar programas que utilizan repeticiones: la no-
cion de recorrido de una secuencia. Cerramos la Unidad con ejercicios completos
que utilizan todas las herramientas vistas.

4.1. Mas sobre alternativas


Como dijimos, una alternativa es una forma de decidir entre otros dos coman-
dos para saber cual de ellos debe ejecutarse, o dicho de otra forma, una manera
de describir una accion que puede ser diferente dependiendo de ciertas condi-
ciones. Tambien vimos la forma mas comun de alternativas, la alternativa condi-
cional, comunmente conocida en la jerga de programacion como condicional o
simplemente sentencia if-then-else.
En este apartado vamos a profundizar sobre algunas combinaciones de alter-
nativas condicionales, y veremos una nueva forma de alternativa, la alternativa
indexada, tambien conocida como sentencia case o sentencia switch.

4.1.1. Alternativa condicional


Los comandos de alternativa condicional pueden anidarse (o sea, usar un con-
dicional en las ramas de otro), para tener diversas alternativas. Por ejemplo, su-
poner que el cabezal representa la posicion de nuestro ejercito y se desea re-
presentar la siguiente accion: si hay enemigos visibles, entonces nuestro ejercito
debe intentar huir al Norte y en caso de no poder, debe esconderse; pero si no

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


114

hay enemigos, debe avanzar hacia el Este, y si no encuentra enemigos al llegar,


debe armar una trinchera, pero si los encuentra, debe atacarlos. El codigo para
resolver este problema podra ser:

if (not hayEnemigosAca())
{
Mover(Este) -- No hay enemigos, y puede avanzar
if (not hayEnemigosAca())
-- El nuevo Aca habla de la celda al
-- Este de la original!!
{ ArmarTrinchera() }
else
{ Atacar() }
}
else
{ -- Hay enemigos, y debe huir o esconderse
if (elCaminoEstaDespejado(Norte)))
{ Mover(Norte) }
else
{ Esconderse() }
}

Observar que la precondicion de este programa es que la celda actual no pue-


de encontrarse en la fila mas al Esteni en la fila mas al Norte. Tambien que no
hace falta conocer la implementacion exacta de las funciones hayEnemigosAca,
elCaminoEstaDespejado o de los procedimientos ArmarTrinchera, Atacar, etc.
para entender este codigo (alcanza con entender sus precondiciones y sus efec-
tos).
Es importante observar que si bien el ejemplo ilustra la posibilidad de anidar
comandos condicionales, quedara de manera mas claro utilizando procedimien-
tos de la siguiente manera.

procedure InvadirPosicionAlEste()
{- PROPOSITO:
* avanza 1 celda al Este y al llegar, decide si arma
una trinchera (si no hay enemigos) o ataca al enemigo.
PRECONDICION:
* hay una celda al Este
-}
{
Mover(Este)
if (not hayEnemigosAca())
{ ArmarTrinchera() }
else
{ Atacar() }
}
procedure HuirOEsconderse()
{- PROPOSITO:
* decide si huir hacia el Norte o esconderse, en base
a las condiciones del camino
PRECONDICION:
* hay una celda al Norte
-}
{
if (elCaminoEstaDespejado(Norte)))

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


115

{ Mover(Norte) }
else
{ Esconderse() }
}
y luego construir el condicional como
if (not hayEnemigosAca())
{ InvadirPosicionAlEste() }
else
{ HuirOEsconderse() }

Actividad de Programacion 1

Realice el ejercicio 4.1.1 y observe como se manifiesta el uso de condi-


cionales anidados.

Ejercicio 4.1.1. Escribir un programa que decida entre un conjunto de acciones,


basandose en un codigo representado en la celda actual con base en bolitas de
colores. Las acciones se representan con los procedimientos DibujarVentana,
RedimensionarVentana, MaximizarVentana y MinimizarVentana. Los codigos
se indican segun la presencia de bolitas en la celda actual. El codigo que indica
que debe dibujarse una ventana es la presencia de bolitas verdes. El codigo que
indica que la ventana debe redimensionarse es la presencia de bolitas azules
(siempre y cuando no haya verdes). El codigo que indica que la ventana debe
maximizarse es la presencia de bolitas negras (pero no verdes ni azules). Y el
codigo que indica que la ventana debe minimizarse es la presencia de bolitas
rojas (pero no de ninguno de los otros 3 colores). Si no hubiera bolitas, entonces
no debe hacerse nada.
Cada condicion utilizada debe escribirse exclusivamente utilizando la funcion
hayBolitas, sin ningun otro conectivo. Ademas, las acciones son disjuntas; o sea
solo debe realizarse una de ellas.
Los condicionales anidados no siempre son necesarios. En muchas ocasiones
pueden ser reemplazados por condiciones mas complejas, a traves del uso de
conectivos logicos y de abstraccion a traves de funciones, como se vio en la
Unidad anterior.

4.1.2. Alternativa indexada


En el ultimo ejemplo del subapartado anterior vimos la posibilidad de decidir en-
tre varias acciones con base en el valor de un codigo. Esta forma de decision
se puede representar, tal cual se vio en dicho ejemplo, mediante condicionales
anidados. Sin embargo, en muchos lenguajes existe otra forma de representar
este tipo de decisiones: la alternativa indexada.
En esta forma de alternativa, se elige entre varios comandos con base en
un ndice, que indica de alguna forma cual de los comandos es el elegido. La
sintaxis en G OBSTONES para alternativas indexadas utiliza la palabra clave case,
y se escribe de la siguiente manera:
case (decodificarCelda()) of
1 -> { DibujarVentana() }
2 -> { RedimensionarVentana() }
3 -> { MaximizarVentana() }

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


116

4 -> { MinimizarVentana() }
_ -> { NoHacerNada() }
En este caso, la funcion decodificarCelda devolvera 1 si en la celda actual
hay bolitas verdes, 2 si hay bolitas azules pero no verdes, 3 si hay bolitas ne-
gras pero no azules ni verdes, 4 si hay solo bolitas rojas, y cualquier otro nume-
ro (por ejemplo, 0) si no hay bolitas en la celda actual (para definir la funcion
decodificarCelda en G OBSTONES hace falta alguna forma de recordar valores,
por lo que volveremos a ella despues de presentar la idea de memoria.) Final-
mente, el procedimiento NoHacerNada no tiene ningun efecto.
En G OBSTONES existe un coman-
do predefinido que no hace nada. Definicion 4.1.1. El comando de alternativa indexada (tambien conocido como
Por razones historicas, el mismo se sentencia case) tiene la siguiente forma:
denomina Skip. Tambien puede im-
plementarse con otros comandos, case (< indexExp >)
por ejemplo, poniendo y sacando < val1 > -> < bloque1 >
una bolita de cierto color de la celda
actual.
..
.
< valn > -> < bloquen >
-> < bloqueDefault >
siendo < indexExp > una expresion que describe un valor de alguno de los ti-
pos basicos, < val1 > a < valn >, una serie de valores de ese tipo, y < bloque1 >,
< bloquen > y < bloquedefult >, una serie de bloques de codigo cualesquiera (que
normalmente son diferentes, aunque podran ser iguales). Al bloque < vari > se
lo denomina rama i-esima (o rama del valor < vali >), para cada i entre 1 y n, y
al bloque < bloqueDefault > se lo denomina rama por defecto (o rama default).

El efecto de un comando case es el de elegir uno de los bloques, en base al valor


de la expresion < indexExp >: si la expresion vale alguno de los < vali >, enton-
ces se elige el bloque < bloquei >, y si su valor no es ninguno de los listados,
entonces se elige el bloque < bloqueDefault >.
Hay dos cuestiones que observar en un case. La primera es que el orden en
el que se elige es secuencial, al igual que en un if; o sea, si el mismo valor
aparece mas de una vez, solo se utilizara su primera aparicion. La segunda es
que la rama default siempre debe aparecer y captura todos los valores posibles
que no se encuentren entre los listados. Esto puede llevar al caso anomalo donde
esta rama nunca se elija, por no quedar valores disponibles.
Para ejemplificar esta situacion, consideremos la necesidad de codificar una
direccion en la celda actual, utilizando bolitas verdes. Un codigo posible sera
procedure CodificarDireccion(dir)
{-
SUPOSICION:
* en la celda actual no hay bolitas verdes
-}
{
case (dir) of
Norte -> { PonerN(Verde,1) }
Sur -> { PonerN(Verde,2) }
Este -> { PonerN(Verde,3) }
_ -> { PonerN(Verde,4) }
}
donde se observa que solo se pregunta por 3 direcciones, siendo innecesario
preguntar por la direccion Oeste en el ultimo caso, porque es la unica opcion
posible. Si quisiesemos explicitar la pregunta sobre cada una de las direcciones,

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


117

el case debera contener igualmente la rama default, pero con codigo que jamas
se ejecutara:

procedure CodificarDirAlternativo(dir)
{
case (dir) of
Norte -> { PonerN(Verde,1) }
Sur -> { PonerN(Verde,2) }
Este -> { PonerN(Verde,3) }
Oeste -> { PonerN(Verde,4) }
_ -> { BOOM("Es imposible que suceda esto!") }
}

En este ejemplo, utilizamos el comando BOOM, que es un comando predefinido


para G OBSTONES cuyo fin es terminar el programa con un mensaje de error que
es dado entre comillas.
Observar que no es imprescindible contar con el comando case, puesto que
el mismo puede ser representado mediante condicionales anidados y el uso del
operador de igualdad ==, de la siguiente manera

if (< indexExp >==< val1 >)


< bloque1 >
else
{ if (< indexExp >==< val2 >) }}
< bloque2 >
else
{ if (. . . )
...
else
< bloqueDefault >

Sin embargo, es mucho mas comodo escribir esta construccion mediante el co-
mando case. En algunos lenguajes donde no existe el comando case, existe una
forma de alternativa condicional que permite varias ramas en el if mediante la P YTHON por ejemplo.
palabra clave elif (abreviatura de else if; ver unidad 5).

Para Reflexionar

Cuando la alternativa indexada se utiliza sobre el tipo de los booleanos,


y el unico valor consultado es el True, la misma es equivalente a una
alternativa condicional. Dicho de otro modo, la alternativa condicional
puede entenderse como una alternativa que indexa sobre booleanos.

Actividad de Programacion 2

Realice el ejercicio 4.1.2 utilizando un case. Luego intente realizarlo uti-


lizando un if-then-else y compare el codigo de ambas soluciones.

Ejercicio 4.1.2. Escribir un procedimiento ProcesarTecla, que dado un numero


codificando a una tecla que fue presionada en algun tipo de interfase, determine
la accion a seguir. Los codigos de teclas y las acciones que debe producir cada
tecla son los siguientes:

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


118

Tecla Codigo Accion


, w 119 Acelerar()
, s 97 Frenar()
, a 115 GirarIzquierda()
, d 100 GirarDerecha()
< espacio > 32 Disparar()
< escape > 27 Terminar()
otras MostrarError()

4.2. Mas sobre repeticiones


Como vimos, una repeticion es un comando que expresa la ejecucion reiterada de
otro comando un cierto numero de veces que se indica con un rango de valores.
En este apartado vamos a profundizar sobre algunas combinaciones de repe-
ticiones indexadas, y veremos una nueva forma de repeticion, la repeticion condi-
cional, tambien conocida como sentencia while o sentencia do-while. Ademas,
veremos una manera de estructurar programas que utilizan repeticion condicio-
nal, denominada por nosotros como recorridos, pensados como repeticiones que
procesan secuencias de elementos. El objetivo de los recorridos es simplificar el
uso de repeticiones condicionales, y evitar la multitud de problemas que pueden
presentarse al utilizar esta poderosa forma de repeticion.

4.2.1. Mas sobre repeticion indexada


Al realizar repeticiones, puede suceder que algunos de los elementos del rango
sobre el que se repite no pueda ser procesado de la misma manera que el resto.
En ese caso, y acorde al enunciado del ejercicio mencionado, el procesamiento
puede utilizar una alternativa condicional para evitar procesar elementos inco-
rrectos. Para ejemplificar esto, consideremos un procedimiento al que podemos
llamar CodificarDireccionDelEnemigo, que indique en cual de las 4 direccio-
nes se encuentra el enemigo. Para este ejemplo vamos a suponer que el enemi-
go se encuentra en solo una de las celdas contiguas a la actual (o sea, no se
ha dispersado. . . ), y que la celda actual no contiene bolitas del color en el que
codificaremos la respuesta. El codigo para dicho procedimiento podra ser

procedure CodificarDireccionDelEnemigo()
{- PRECOND:
* no hay bolitas verdes en la celda actual
* solo una de las celdas contiguas tiene enemigos
-}
{
repeatWith dir in minDir()..maxDir()
{
if (puedeMover(dir))
{
if (hayEnemigosAl(dir))
{ Codificar(dir) }
}
}
}

Se puede observar que hay una repeticion sobre las 4 direcciones, para verificar
por turnos en las 4 celdas contiguas. Pero que sucede si la celda actual no tiene

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


119

G.4.1. Guarda de bolitas verdes en cantidades pares

4 celdas contiguas? En ese caso, en esa direccion no se debe verificar, porque


eso producira la autodestruccion del cabezal; para eso se utiliza la alternativa
condicional que pregunta si se puede mover en la direccion que se esta pro-
cesando. La funcion hayEnemigosAl es la que se definio en el ejercicio 3.3.3, y
el procedimiento Codificar se presento en el apartado de alternativa indexada.
Observar que la precondicion de hayEnemigosAl es que pueda moverse en la
direccion suministrada como parametro, y por lo tanto, no debe preguntarse si
hay enemigos hasta no saber que puede moverse en dicha direccion.

Actividad de Programacion 3

Pruebe la funcion CodificarDireccionDelEnemigo en un programa, lue-


go de colocar convenientemente todos los procedimientos y funciones
necesarias y armar correctamente un procedimiento principal.

Otra detalle a observar en la repeticion indexada es que la forma basica de la


misma utiliza todos rangos que incluan todos los numeros entre 2 dados (por
ejemplo, de 1 a 10) de forma creciente, y como maxima complicacion, hacer que
el rango dependiese de un parametro, para poder modificar la cantidad (como en
el ejercicio 3.1.2). Sin embargo, a veces es necesario realizar repeticiones que
requieren rangos de numeros no consecutivos, e incluso rangos descendentes.
Por ejemplo, uno puede querer realizar una guarda de bolitas que solo incluya
bolitas pares, como en el grafico G.4.1. Observar que la guarda tiene 2 partes cla-
ramente diferenciadas: una parte creciente, con bolitas en cantidad par (2,4,6,8 y
10), y otra parte decreciente, tambien con bolitas en cantidad par (10,8,6,4 y 2).
Como podemos lograr esto mediante una repeticion indexada? Claramente, y
como los ndices son siempre crecientes y avanzando de a uno, debemos utilizar
alguna relacion entre los numeros 1,2,3,4 y 5, y los numeros 2,4,6,8 y 10, prime-
ro, y los numeros 10,8,6,4 y 2, luego. En el primer caso, la relacion es sencilla: al
1 le corresponde el 2, al 2 le corresponde el 4, al 3, el 6. . . claramente al numero
i le debe corresponder el numero 2*i. Esto se expresa como:
repeatWith i in 1..5 { PonerN(2*i, Verde); Mover(Este) }
donde podemos observar que la cantidad de bolitas a poner responde a la formu-
la deducida. Para la segunda relacion, vemos que la relacion es inversa, porque
el numero debe decrecer. Para lograr que una secuencia decrezca, podemos
restar una secuencia creciente a partir de un numero fijo. Si pensamos en la se-
cuencia de pares calculada primero, y queremos darla vuelta, deberamos pensar

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


120

una formula que permita obtener un 10 a partir de un 2, un 8 a partir de un 4, un


6 a partir de un 6, etc. Esto se puede obtener restando 12-(2*i).

Actividad de Programacion 4

Realice el ejercicio 4.2.1, basandose en las ideas explicadas hasta aqu,


y obtenga una guarda similar a la del grafico G.4.1.

Ejercicio 4.2.1. Escribir un procedimiento GuardaDePares, que permita realizar


una guarda de bolitas verdes similar a la del grafico G.4.1. Utilizar dos repeticio-
nes indexadas, adaptando los ndices de manera conveniente.
Resumiendo lo analizado hasta aqu, podemos obtener secuencias regulares que
no sean crecientes o de a uno a traves de formulas aplicadas a los ndices. Pa-
ra secuencias con incrementos mayores a uno se utilizan multiplicaciones; para
secuencias decrecientes, se resta una secuencia creciente a un tope dado.

Para Reflexionar

Si bien las repeticiones indexadas en G OBSTONES son siempre de uno


en uno, pueden obtenerse otros rangos a partir del uso de formulas.
Aunque este curso no hace uso de una matematica intensiva, reflexione
sobre la importancia de tener un buen manejo matematico y numerico
para realizar programas mas complejos. Piense en las facilidades que
podran proveer los lenguajes para simplificar la matematica necesaria.

Mediante estas repeticiones indexadas con diferentes rangos podemos revisar


algunos de los ejercicios vistos en la unidad 2.

Actividad de Programacion 5

Realice los ejercicios 4.2.2 y 4.2.3, y verifique que obtienen los mismos
resultados que los originales que mejoran.

Ejercicio 4.2.2. Rehacer el ejercicio 2.4.12 para generalizar el tamano de la ba-


se del triangulo. Observar que se requiere como precondicion que el tamano de la
base sea un numero impar. Completar la precondicion con la cantidad de celdas
que debe haber disponibles para el dibujo.

Leer con Atencion

Hasta el momento habamos visto ejemplos donde la precondicion indi-


caba los requisitos necesarios para que el programa no se autodestruye-
se. Sin embargo, las precondiciones se usan en general para establecer
los requisitos necesarios para que el programa funcione como se espe-
ra. De esta manera, no es siempre necesario que si la precondicion no
se cumple, el programa debe autodestruirse; muchas veces el progra-
ma parece funcionar, pero hace cosas que no son lo que se esperaba
del mismo (como dibujar de forma incompleta una figura). Esta forma
de utilizar precondiciones ofrece gran flexibilidad a la hora de disenar
procedimientos y ayuda a evitar controles innecesarios de condiciones.

En el caso del triangulo, segun la solucion que uno adopte, al invocar el proce-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


121

G.4.2. Resultado de invocar DibujarTrianguloBase(8) (sin cumplir la precondi-


cion): observar que no es exactamente un triangulo

dimiento con un numero par (o sea, no cumpliendo la precondicion), el dibujo no


resultara en un triangulo. Por ejemplo, en la solucion que pensamos nosotros, al
invocar DibujarTrianguloBase(8) queda un dibujo como el que mostramos en
el grafico G.4.2, que no es exactamente un triangulo de base 8, sino uno de base
7 con una pata.

Ejercicio 4.2.3. Rehacer el ejercicio 2.4.13 utilizando una repeticion de 1 a 3.


Observar que los numeros impares obedecen, en este caso, a la formula (2i+3),
siendo i el ndice de la repeticion, y que si uno los quiere en orden inverso, debe
restarlos del tope de 14.

Leer con Atencion

Se pueden conseguir formulas mucho mas complejas que permitan ob-


tener secuencias no regulares a traves del uso de funciones que calcu-
len los resultados esperados, por ejemplo, una secuencia de numeros
primos, o secuencias con pasos variables en distintas partes, etcetera.

4.2.2. Repeticion condicional


Sabemos que la repeticion indexada repite un bloque de codigo un numero fijo de
veces, cantidad que es controlada por un rango de valores. Ahora bien, que de-
bemos hacer si no conocemos de antemano la cantidad de veces que debemos
repetir un comando? Por ejemplo, imaginemos que queremos movernos hasta el
borde del tablero. Puesto que no tenemos en G OBSTONES forma de conocer las
dimensiones del mismo, no hay manera de saber cuantas veces debemos mover-
nos! Situaciones similares a esta se presentan numerosas veces. Considerar por
ejemplo que cuando uno busca sus llaves repite la accion de buscar en lugares,
pero no sabe de antemano en cuantos lugares debe buscar.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


122

Claramente no se trata de adivinar una cantidad, sino de proveer alguna he-


rramienta que permita realizar una repeticion controlada de otra forma, y no me-
diante un ndice. Esta forma se denomina repeticion condicional, pues la misma
permite repetir un comando un numero arbitrario de veces, dependiendo de que
una condicion se cumpla o no. El comando para describir una repeticion condi-
cional es llamado while, que en ingles significa mientras, para marcar que el
bloque a repetir sera iterado mientras se cumpla cierta condicion. La forma de
este comando se establece en la siguiente definicion:

Definicion 4.2.1. La repeticion condicional es una forma de repeticion que de-


pende de una condicion booleana para indicar cuando debe cesar de iterarse. La
forma del comando que describe esta repeticion es

while (< condicion >)


< bloque >

donde < condicion > es una expresion booleana y < bloque > un bloque cualquie-
ra al que se denomina cuerpo de la repeticion.

El efecto del comando while es la repeticion del comando descrito por el < bloque >
mientras la < condicion > sea verdadera. Para obtener este efecto, la ejecucion
del comando comienza evaluando la < condicion > en el estado actual. Si esta
evaluacion resulta verdadera (o sea, la expresion < condicion > evalua a True),
se realiza una iteracion del comando descrito por el < bloque >, y a continuacion
se vuelve a evaluar la condicion. Esto ultimo se repite hasta tanto la condicion
resulte falsa, en cuyo caso termina la ejecucion del comando. Observar que es
necesario que el bloque del cuerpo altere el estado de tal manera que la condi-
cion llegue a resultar falsa en algun momento.
La repeticion condicional es util cuando se trata de realizar una tarea repetitiva
de la que no se sabe a priori cuantas veces debe repetirse (o sea, no se puede
generar un rango sobre el cual realizar la iteracion). El ejemplo mas sencillo de
uso de repeticion condicional es llevar el cabezal hasta un borde del tablero. El
siguiente codigo lleva el cabezal hasta el borde superior:

procedure CabezalAlTopeDeLaColumna()
{- PROPOSITO:
* ilustrar el uso de while
* llevar el cabezal a la ultima fila de la columna actual
PRECONDICION:
* es una operacion total
-}
{
while (puedeMover(Norte))
{ Mover(Norte) }
}

Observar que no hay manera de realizar esta tarea con una repeticion indexa-
da pues no se conoce de antemano el numero de celdas que debera moverse
el cabezal. Asimismo, el cuerpo del while modifica el estado, y en determinado
momento esa modificacion hace que la condicion pase a ser falsa, dando por fi-
Esto es as porque el tablero es fi- nalizada la ejecucion del comando. Esta tarea no podra hacerse con repeticion
nito. indexada, pues no se conoce el tamano del tablero, ni hay forma de determinar
la posicion de la celda actual. Pero s podra parametrizarse, lo cual se evidencia
en el proximo ejercicio.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


123

Actividad de Programacion 6

Realice el ejercicio 4.2.4, y pruebelo con distintas direcciones.

Ejercicio 4.2.4. Escribir un procedimiento IrAlExtremo, que dada una direccion,


se mueve en esa direccion hasta que llega al borde del tablero.

La repeticion condicional es una de las formas mas poderosas de repeticion,


y por ello, tambien mas difcil de manejar correctamente. Por ejemplo, podra
suceder que la condicion jamas se hiciese verdadera. En este caso, el programa
provocara que la maquina quede infinitamente intentando realizar una tarea, lo
cual no puede ser comprobado de ninguna forma externa durante la ejecucion.
Como ejemplo, considerar el siguiente codigo:

procedure LaBuenaPipa()
{- PROPOSITO:
* ilustrar una repeticion cuya ejecucion no termina
PRECONDICION:
* Falsa: el programa jamas termina, por lo que nunca
produce ningun resultado
-}
{
QueresQueTeCuenteElCuentoDeLaBuenaPipa()
while (True)
{
YoNoDije_True_Dije_QueresQueTeCuenteElCuentoDeLaBuenaPipa()
}
}

Donde los dos procedimientos internos son cualesquiera que definan operacio-
nes totales. Es claro que como la respuesta es siempre la misma, este cuento
seguira para siempre. Esta capacidad de ejecutar infinitamente es equiparable a
la autodestruccion del cabezal, en tanto y en cuanto no produce un tablero deter-
minado. Sin embargo, su manifestacion es diferente, pues se limita a mantener
una apariencia de trabajo cuando en realidad no hay ningun trabajo que termine
dando beneficios. A pesar de tener esta manifestacion diferente, la precondicion
de un procedimiento debe incluir las condiciones para asegurar que todas las
repeticiones condicionales terminan. Por ejemplo, considerar el siguiente codigo:

procedure MoverseHastaElBorde(d1, d2)


{- PROPOSITO:
* ilustrar el uso de precondiciones para
evitar no terminacion
* moverse simultaneamente en dos direcciones,
hasta alcanzar el borde del tablero
PRECONDICION:
* d1 y d2 no pueden ser direcciones opuestas
-}
{
while (puedeMover(d1) && puedeMover(d2))
{ Mover(d1); Mover(d2) }
}

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


124

Observar que la condicion establece que el valor de los parametros debe ser tal
que no sean direcciones opuestas. Si las direcciones son opuestas (por ejemplo,
una es Norte y la otra es Sur), los efectos de ambos Mover se anularan, y la
repeticion no terminara nunca, provocando la ejecucion infinita. En cualquier otro
caso los efectos se iran acumulando haciendo que a la larga se alcance el borde
del tablero, por lo que el procedimiento se dentendra.
Para controlar este poder de la repeticion condicional, presentamos a conti-
nuacion la idea de recorrido.

4.2.3. Recorridos simples

Es usual que muchas veces al pensar una tarea que involucra repeticion, ten-
gamos en mente alguna secuencia de elementos. Por ejemplo, si buscamos pro-
cesar todas las celdas de una columna pintando cada una de ellas de un color
determinado, la secuencia en cuestion es la secuencia de celdas de la columna
actual. En ese caso, el programa podra escribirse como:

procedure PintarColumna(color)
{- PROPOSITO:
* pinta una columna entera con bolitas de color
PRECONDICION:
* ninguna, es una operacion total
-}
{
-- empieza arriba de todo para estar seguro
-- que las procesa todas
CabezalAlTopeDeLaColumna()

while (not llegoALaBase())


-- todava falta procesar celdas
{
PintarCeldaDe(color) -- procesar la celda
Mover(Sur) -- pasar a la siguiente celda
}

-- pinta la ultima celda, pues no entro al while


-- si la celda estaba en la base (y por lo tanto,
-- no la pinto)
PintarCeldaDe(color)
}

Aqu podemos observar varios puntos interesantes. El primero es que se co-


mienza llevando el cabezal al tope de la columna para asegurarse que todas las
celdas resultaran pintadas. Otro mas es que al finalizar el ciclo hace falta pintar
la ultima celda a mano, pues el pintar la celda dentro del ciclo no se realiza sobre
la ultima celda (ya que desde ella no se puede mover al Sur). Finalmente, vemos
que dentro de la repeticion hay una parte que procesa la celda actual, y otra que
se ubica en el siguiente elemento de la secuencia.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


125

Actividad de Programacion 7

Realice el ejercicio 4.2.5. Utilice el procedimiento PintarColumna


en un programa completo. Recuerde copiar el codigo de
CabezalATopeDeLaColumna en su programa.

Ejercicio 4.2.5. Completar las operaciones llegoALaBase y PintarCeldaDe.


La funcion llegoALaBase verifica si el cabezal se encuentra en la base de la
columna, i.e. en la celda que se encuentra mas al Sur (o sea, no puede moverse
mas hacia el sur). El procedimiento PintarCeldaDe simplemente pone una o mas
bolitas del color indicado.
Esta forma de repeticion condicional aparece una y otra vez, segun cual sea la
secuencia de elementos que consideremos. Por ejemplo, si en lugar de pintar una
columna de un color determinado, quisieramos pintar todo el tablero, podramos
hacer un recorrido sobre todas las columnas, pintando cada una de ellas. El
procedimiento quedara muy parecido al de PintarColumna, pues la estructura
del problema es la misma:
procedure PintarTablero(color)
{- PROPOSITO:
* pinta todo el tablero con bolitas de color
PRECONDICION:
* ninguna, es una operacion total
-}
{
-- va a la primera columna para saber que las hace todas
CabezalALaPrimeraColumna()

while (not llegoALaUltimaFila())


-- todava falta procesar columnas
{
PintarColumna(color) -- pintar columna de color
Mover(Este) -- pasar a la siguiente columna
}

-- pinta la ultima columna, pues no entro al while si


-- la columna era la ultima
PintarColumna(color)
}
Al igual que en PintarColumna, no es posible utilizar una repeticion indexada,
pues no se conoce de antemano el numero de columnas. Ademas, se observa
que el esquema de resolucion es el mismo: se comienza ubicando la primera
columna, y a partir de ah se van pintando cada una de ellas (utilizando el pro-
cedimiento PintarColumna), hasta la ultima, que debe ser pintada de manera
separada pues la ultima columna no satisface la condicion del while.

Actividad de Programacion 8

Realice el ejercicio 4.2.6. Utilice el procedimiento PintarTablero en un


programa. Recuerde incluir todo el codigo en su programa!

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


126

Ejercicio 4.2.6. Completar el codigo anterior. Para ello, debe escribir la funcion
llegoALaUltimaFila, que establece si el cabezal se encuentra en la fila mas al
Este (o sea, no puede moverse mas hacia el este) y tambien el procedimiento
CabezalALaPrimeraColumna que lleva el cabezal a la primera columna del tablero
(similar al procedimiento CabezalATopeDeLaColumna).

Este esquema de repeticion donde se realiza una tarea para cada uno de una
serie de elementos se denomina recorrido, pues recorre la secuencia de elemen-
tos de a uno, procesando de alguna forma cada uno de ellos. El esquema que
siguen todos los recorridos es el siguiente:
procedure RecorridoGenerico()
{- PROPOSITO:
* recorre una secuencia de elementos genericos, segun
las definiciones que se den a las partes
PRECONDICION:
* depende de las definiciones que se den a las partes
-}
{
IniciarRecorrido()
-- todo lo necesario para recorrer los elementos:
-- ubicarse en el primero de ellos,
-- preparar lo que haga falta, etc.

while (not llegoAlUltimoElemento())


-- todava falta procesar elementos
{
ProcesarElementoActual() -- procesa de alguna forma
-- el elemento actual
PasarAlSiguiente() -- pasar al siguiente elemento
}

FinalizarRecorrido()
-- termina el recorrido, cerrando lo necesario
-- y completando el trabajo
}
Los procedimientos utilizados en este codigo son operaciones genericas (al igual
que sus nombres), y deben reemplazarse por las operaciones correspondientes
a la secuencia de elementos que quiere recorrerse. Por ejemplo, en el caso de
PintarColumna, la correspondencia entre las operaciones genericas y las reales
es la siguiente:

Operacion generica Operacion real


IniciarRecorrido() CabezalAlTopeDeLaColumna()
ProcesarElementoActual() PintarCeldaDe(color)
PasarAlSiguiente() Mover(Sur)
FinalizarRecorrido() PintarCeldaDe(color)
llegoAlUltimoElemento() llegoALaBase()

Como se puede observar, puede haber variaciones entre el procedimiento generi-


co y el real, por ejemplo, agregando parametros, o realizando una (o varias) ope-
raciones elementales (como Mover(Sur)), o incluso no realizando ninguna ope-
racion. Sin embargo, lo importante del recorrido es que se encarga de recorrer y
procesar cada uno de los elementos de la secuencia considerada.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


127

Actividad 9

Realice la correspondencia entre operaciones genericas y operaciones


reales en el procedimiento PintarTablero. Luego realice la correspon-
dencia para el procedimiento CabezalAlTopeDeLaColumna. Tenga en
cuenta que en este ultimo caso habra 3 operaciones que no realicen
nada.

El recorrido tampoco tiene por que procesar todos los elementos. Por ejemplo, si
consideramos que una columna es un cantero, y queremos recorrer cada sector
del cantero (representado cada uno con una celda), colocando fertilizante (bolitas
negras) solo en aquellos sectores donde haya flores (bolitas rojas), el codigo
podra ser el siguiente

procedure FertilizarFlores()
{- PROPOSITO:
* Poner fertilizante en las celdas de la
columna que contengan flores
PRECONDICION:
* ninguna, es una operacion total
-}
{
-- va al tope para saber que las hace todas
IrAlExtremo(Norte)

while (puedeMover(Sur))
-- la condicion dice "no llego a la base"
{
if (hayFlor()) -- solo se agrega en las celdas
{ Fertilizar() } -- que cumplen la condicion
Mover(Sur) -- pasar a la siguiente celda
}

-- realiza la accion en la ultima celda, pues no entro


-- al while si la celda no tena una al Sur
if (hayFlor())
{ Fertilizar() }
}

Podemos observar que la operacion de procesar elemento actual, en este caso,


es condicional a que se cumpla la existencia de una flor en la celda. De esta
manera, solo las celdas con flores seran fertilizadas.

Actividad de Programacion 10

Pase el procedimiento anterior, complete sus subtareas, y pruebelo en


un programa con varios tableros diferentes.

La secuencia de elementos no tiene por que aparecer de manera lineal en la


visualizacion en el tablero. Por ejemplo, si tomamos un sendero y lo seguimos,
podemos considerar a las posiciones del sendero como los elementos a procesar.
Veamos como sera, definiendo bien la idea de sendero y haciendo un programa
que lo procese de alguna manera.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


128

G.4.3. Sendero simple con forma aproximada de 52

Un sendero simple se indica en el tablero mediante una serie de bolitas ne-


gras contiguas una de las otras, de manera que cada bolita no tiene nunca mas
de dos vecinas (excepto la primera y la ultima). La primera celda del sendero se
indica con 2 bolitas negras y es siempre la celda mas al sur y el oeste (el origen
del tablero), y la ultima con 3 bolitas negras y puede ser cualquiera. Es importan-
te remarcar que la celda inicial con 2 bolitas y la celda final con 3 bolitas son las
unicas de todo el tablero que tienen esta cantidad de bolitas negras. Podemos ver
un ejemplo de sendero en el grafico G.4.3. Observar que cada celda interna del
sendero tiene a lo sumo dos celdas contiguas (en las cuatro direcciones cardi-
nales) que contienen bolitas. De esta manera, si comenzamos en la celda inicial
del sendero, es sencillo saber cual es la proxima celda a visitar: la unica de las
contiguas que tiene bolitas negras y en la que no estuvimos antes. Ahora supon-
gamos que la intencion es colocar una rosa (representada mediante una bolita
roja) en cada celda del sendero. As, podemos realizar esta tarea definiendo las
siguientes operaciones, y luego armando un recorrido con ellas:

Operacion generica Operacion real


IniciarRecorrido() BuscarInicioSendero()
ProcesarElementoActual() ColocarRosa()
PasarAlSiguiente() MoverASiguienteSector()
FinalizarRecorrido() ColocarRosa()
VolverAlInicioDelSendero()
llegoAlUltimoElemento() esFinDelSendero()

La operacion de ColocarRosa es sencilla, y similar a las que ya vimos antes. La


condicion de esFinDelSendero tambien es sencilla, pues alcanza con mirar el

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


129

numero de bolitas negras de la celda actual. Las operaciones dadas por los pro-
cedimientos BuscarInicioSendero y VolverAlInicioDelSendero son, en esta
forma simplificada de senderos, nada mas que IrAlOrigen. Entonces, la ope-
racion interesante esMoverASiguienteSector, que es una busqueda por las 4
celdas contiguas de aquella que tenga bolitas negras pero no tenga flores y lue-
go moverse all. Se puede realizar con dos subtareas, de la siguiente manera

procedure MoverASiguienteSector()
{-
PRECOND:
* La celda actual no tiene bolitas verdes
* La celda actual es parte de un camino simple
* Una de los dos sectores contiguos ya fue visitado
y tiene una flor
-}
{
-- Elegir la direccion para seguir y codificarla
repeatWith dir in minDir()..maxDir()
{
if (puedeMover(dir))
{
if (haySectorNoVisitadoAl(dir))
{ CodificarDireccion(dir) }
}
}
DecodificarDireccion()
}

La primera parte trabaja de manera similar al procedimiento del apartado 4.2.1,


CodificarDireccionDelEnemigo, codificando la direccion en la que hay bolitas
negras pero no rojas, teniendo en cuenta que sucede en las celdas que no tie-
nen 4 contiguas. Y luego una segunda parte decodifica la direccion, mirando el
numero de bolitas verdes (usando, por ejemplo, una alternativa indexada), y con
base en ese numero, saca todas las verdes y se mueve en la direccion corres-
pondiente. Observar que debe hacerse en dos partes, porque si no, no habra
forma de saber si debemos parar de mirar las celdas vecinas! Tambien hay que
observar que el procedimiento DecodificarDireccion debe eliminar las bolitas
verdes despues de leerlas, as no quedan en el tablero.
Una vez codificadas todas las partes, podemos definir el procedimiento como

procedure PonerFloresEnSenderoSimple()
{
BuscarInicioSendero() -- iniciar recorrido
while (not esFinDelSendero())
-- no termino el recorrido
{
ColocarRosa() -- procesar elemento
MoverASiguienteSector() -- pasar al siguiente
}
ColocarRosa() -- finalizar recorrido
VolverAlInicio() -- "
}

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


130

Actividad de Programacion 11

Pase el codigo del procedimiento PonerFloresEnSenderoSimple, junto


con todas sus partes (codificando las que faltan segun el ejercicio 4.2.7),
y pruebelo en el tablero de ejemplo mostrado en el grafico G.4.3.

Ejercicio 4.2.7. Escribir las operaciones

ColocarRosa,

esFinDelSendero,

BuscarInicioSendero,

VolverAlInicioDelSendero y

DecodificarDireccion (del procedimiento MoverASiguienteSector),

segun las ayudas ofrecidas previamente. Una sutileza interesante es que en el


caso del procedimiento VolverAlInicioDelSendero, se debera considerar sim-
plemente llamar a BuscarInicioSendero, para no tener que rehacer aquella en
caso de que esta ultima cambie.

Una forma de mejorar la definicion de sendero es quitar la restriccion de que


la celda inicial se encuentre en el origen. Al hacer esto, deberemos modificar
BuscarInicioSendero para que sea un recorrido sobre todas las celdas del ta-
blero, buscando aquella que tenga exactamente 2 bolitas negras. Es interesante
pensar en un recorrido sobre todas las celdas que se detenga al encontrar la
celda buscada. La estructura sera la siguiente

procedure BuscarInicioSendero()
{-
PRECOND:
* hay una unica celda que es el inicio del sendero
(indicada con 2 bolitas negras)
-}
{
IrAlOrigen()
while(not esInicioDelSendero())
{
PasarASiguienteCelda()
}
}

Este es un recorrido de busqueda, y podemos observar varias cosas en el. La


primera, mas obvia, es que no hay que procesar la celda (mas que para visitar-
la) pues estamos buscando una, y las que no son, no precisan procesamiento,
ni tampoco hay que finalizar el recorrido (porque al llegar ya esta lo que haba
que hacer). La segunda, mas sutil, es que el recorrido corta al encontrar la celda
buscada; o sea, en rigor, es un recorrido sobre las celdas previas a la que busca-
mos. La ultima cosa a observar es que el procedimiento PasarASiguienteCelda
no es trivial, porque las celdas estan dispuestas en un cuadriculado. El codigo
para este procedimiento es

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


131

procedure PasarASiguienteCelda()
{
if (puedeMover(Norte))
{ Mover(Norte) }
else
{ IrAlExtremo(Sur); Mover(Este) }
}

Actividad de Programacion 12

Modifique el codigo del procedimiento BuscarInicioDelSendero, y lue-


go vuelva a probar el procedimiento PonerFloresEnSenderoSimple, en
un tablero que contenga un sendero simple diferente al del ejemplo an-
terior.

Volveremos a revisar la idea de recorrido una vez que hayamos presentado una
de las herramientas mas poderosas (y mas complejas de utilizar) que tienen los
lenguajes de programacion: la memoria.

4.3. Memorizacion de datos


Es notable, hasta el momento, que cuando el cabezal se mueve por el tablero,
no tenemos una forma de recordar informacion, tal como el numero de bolitas
de las celdas que ya vimos. Esta dificultad hace que ciertas tareas se vuelvan
complicadas de resolver, o directamente imposibles. Por ejemplo, para contar la
cantidad de enemigos que estan cerca, en el ejercicio 3.3.5 utilizabamos como
memoria la cantidad de bolitas de cierto color en la celda actual; o tambien, pa-
ra determinar en que direccion esta el proximo segmento del sendero, debamos
codificar la direccion con bolitas verdes en la celda actual. Estas tareas seran
mucho mas sencillas si el cabezal tuviese memoria para recordar valores es-
pecficos.

4.3.1. Variables
La palabra variable sufre de un pro-
Para conseguir que el cabezal recuerde cosas mediante una memoria, se puede
blema: en distintos contextos tiene
utilizar la misma idea de dar nombres a expresiones que ya fueron utilizadas en distintos significados. As, un ma-
los parametros de un procedimiento y en el ndice de una repeticion indexada. En tematico entendera una cosa por
ambos casos usamos una forma limitada de memoria, donde el cabezal recuerda variable, mientras que un progra-
mador puede entender otra. Por
un valor dado por cierto tiempo (por ejemplo un argumento, mediante el nombre eso debemos ser cuidadosos en
del parametro, mientras dura la ejecucion de un procedimiento). Esta misma idea respetar las formas de entender un
de nombrar valores puede utilizarse de manera independiente y controlada por termino de cada disciplina.
el progamador. Para ello, se define la nocion de variable, que no es mas que
un identificador que se utiliza para denotar algun valor en cierto momento de
la ejecucion de un programa. O sea, la forma de proveer memoria es mediante
la capacidad de nombrar valores y sabiendo que nombre le dimos, recordar
el valor; o sea, establecemos una correspondencia entre un nombre y un valor
dado. Para establecer la correspondencia entre una variable y el valor que la
misma denota se utiliza un comando particular, conocido como asignacion.
Definicion 4.3.1. Una variable es un identificador que comienza con minusculas
y que se utiliza para denotar un valor en cierto momento de la ejecucion de un
programa.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


132

La asignacion de un nombre a un valor determinado se realiza escribiendo el


nombre de la variable, luego el signo :=, y luego la expresion que describe el
valor que la variable debe nombrar. Por ejemplo

cantidadRojas := nroBolitas(Rojo)

establece la correspondencia entre la variable llamada cantidadRojas y el nume-


ro de bolitas de la celda en la que se encuentra el cabezal al ejecutar este co-
mando. Tambien decimos que asigna el valor actual de nroBolitas(Rojo) a la
variable cantidadRojas.

Leer con Atencion

Dicho de otra forma, cantidadRojas nombra a la cantidad de bolitas de


la celda actual en ese momento de la ejecucion, se transforma, tempo-
ralmente (hasta la proxima asignacion de dicha variable) en otra forma
de describir a ese valor. El valor descrito es el numero de bolitas ro-
jas en una celda determinada en un instante determinado, y no en
la celda actual en otros momentos, ni siquiera el numero de bolitas de
esa celda en cualquier momento anterior o posterior, donde la cantidad
puede haber variado. Esto es importante recordarlo, pues es fuente de
mucha confusion. Si luego el cabezal se mueve o la cantidad cambia,
cantidadRojas seguira nombrando al valor de aquella celda en aquel
momento.

La forma general de la asignacion queda dada por la siguiente definicion:

Definicion 4.3.2. La asignacion es un comando mediante el cual se establece la


correspondencia entre un nombre y un cierto valor. Su forma es

< variable > := < expresion >

siendo < variable > un identificador con minusculas, y < expresion > una expre-
sion cualquiera que describe (o denota) al valor que se quiere asociar (asignar)
al nombre de la variable.

El efecto de la accion descrita por un comando de asignacion es la de recordar


que el nombre de la variable se usara para denotar al valor descrito por la expre-
sion. Debe destacarse que la expresion puede ser cualquiera de las vistas, de
cualquier complejidad.
Una cuestion importante sobre la forma de hablar de variables es que usare-
mos como sinonimos el valor descrito por la variable y el valor de la variable,
y tambien la variable describe a un valor y la variable toma un valor. Si bien
las segundas formas en cada caso no son totalmente correctas desde el punto
de vista del castellano, son terminologas ampliamente difundidas y utilizadas. Es
importante no tomar literalmente estas formas descuidadas de hablar de varia-
bles, pues pueden conducir a confusiones.
Para efectivizar la accion descrita por un comando de asignacion, el cabezal
primero calcula el valor de la expresion, y luego establece la correspondencia
entre la variable y ese valor. Es importante volver a remarcar que el valor que la
variable nombra sera el mismo aun si el valor de la expresion cambia a posteriori
de la asignacion (a menos que se realice una nueva asignacion). Para observar
este fenomeno, puede estudiarse el siguiente ejemplo:

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


133

(a). Tablero inicial (b). Tablero final

G.4.4. Prueba del procedimiento CopiarVerdesAlNorte

procedure CopiarVerdesAlNorte()
{- PROPOSITO:
* ilustra el uso de variables y el hecho de que la
correspondencia no cambia aunque la expresion usada
para definirla s lo haga
PRECONDICION:
* debe haber una celda al Norte
SUPOSICION:
* la celda al Norte se encuentra vaca
-}
{
cantVerdes := nroBolitas(Verde)
-- Recuerda el nro de bolitas de la celda inicial
Mover(Norte)
-- Se mueve al Norte
PonerN(Verde, cantVerdes)
-- Pone en la nueva celda la cantidad recordada
-- (observar que se supone que esta celda no
-- tiene bolitas)
Mover(Sur)
}
El valor que se asocia a cantVerdes es el numero de bolitas que hay en la celda
inicial, e incluso despues de que el cabezal se mueva, la variable seguira tenien-
do el valor de la celda inicial, aunque la nueva celda no tenga dicha cantidad. La celda inicial es la celda actual
En este ejemplo, suponemos que la celda al Norte no tiene bolitas, y que la cuando inicia el procedimiento.
inicial s las tiene. Podemos observar el efecto de este procedimiento en el grafi-
co G.4.4.

Actividad de Programacion 13

Copie el codigo del procedimiento CopiarVerdesAlNorte en un progra-


ma, completelo con las definiciones faltantes, y pruebelo con varias con-
figuraciones de tableros diferentes.

Las variables son utiles para recordar ciertos valores al moverse por el table-
ro. Por ejemplo, en el siguiente ejercicio deberan usarse variables cantRojas,

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


134

cantVerdes, cantAzules y cantNegras.

Actividad de Programacion 14

Realice el ejercicio 4.3.1 y pruebelo con varias celdas con distinto nume-
ro de bolitas de diversos colores.

Ejercicio 4.3.1. Escribir un procedimiento CopiarCeldaAl que, dada una direc-


cion dir, y suponiendo que la celda lindante en esa direccion no tiene bolitas,
haga que dicha celda termine con el mismo numero de bolitas de cada color que
la celda inicial. El procedimiento debe realizar solo dos movimientos del cabezal,
y debe dejar el cabezal en el lugar de inicio.
Sugerencia: considerar el uso de cuatro variables denominadas cantRojas,
cantVerdes, cantAzules y cantNegras.

Las variables pueden nombrar valores de cualquier tipo. Por ejemplo, suponga-
mos que las bolitas en una celda cuentan votos, y que queremos indicar en la
celda del origen el ganador de la votacion con una bolita del color correspon-
diente (suponemos ademas que en caso de empate, gana el color mas chico, o
sea, el que este mas cerca del inicio del alfabeto). Podra, entonces, usarse el
procedimiento que se presenta a continuacion

procedure RecuentoDeVotos()
{- PROPOSITO:
* colocar en la celda del origen, una bolita del color
de las que haya mas en la celda actual
-}
{
colorAPoner := colorConMasCantidad()
IrAlOrigen()
Poner(colorAPoner)
}

donde la funcion colorConMasCantidad retorna el color del que hay mas bolitas
en la celda actual (y si hay mas de uno, retorna el menor de todos); esta fun-
cion sera definida mas adelante. Se observa que el valor descrito por la variable
colorAPoner es un color (pues se usa como argumento del comando Poner).
Tambien pueden guardarse direcciones y booleanos en variables, ademas de
numeros y colores.

Leer con Atencion

Si bien las variables pueden asignarse con valores de diferentes tipos,


es conveniente que cada variable se utilice siempre para valores de un
tipo especfico. Hay lenguajes que permiten que las variables recuerden
cualquier cosa, pero otros que solo permiten que una variable guarde
elementos de un unico tipo. Estas diferencias exceden el alcance de este
curso, pero es importante que al aprender nuevos lenguajes se preste
atencion a esta clase de restricciones.

Ahora bien, que sucedera si se intenta usar una variable a la que no se le


asigno ningun valor? Sencillamente, eso provoca la autodestruccion del cabezal.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


135

Un caso muy simple de cometer este error es realizar una asignacion en alguna
de las ramas de un condicional, y olvidarlo en la otra.
Por ejemplo, supongamos que queremos enviar al cabezal a que encienda
una luz roja en la celda de origen (representando la luz con una bolita de ese
color) si el cultivo en la celda actual (representado tambien con distintas bolitas)
ha comenzado a ponerse negro y que encienda una luz verde en aquella celda,
si el cultivo se conserva azul. El codigo propuesto para esta tarea es
procedure AvisarEstadoDelCultivo()
{-
PRECOND:
* debe haber bolitas negras o azules
en la celda actual
-}
{
if (hayBolitas(Negro))
-- El cultivo se empezo a poner Negro
{ colorAEncender := Rojo }
else
{ if (hayBolitas(Azul))
-- El cultivo conserva su color Azul
{ colorAEncender := Verde }
}
IrAlOrigen()
Poner(colorAEncender)
-- Encender la luz correspondiente
}
Sin embargo, el codigo del ejemplo contiene un error potencial. En el caso de
que el cultivo se haya muerto (o sea no haya bolitas de ningun color), la variable
colorAEncender no tendra valor, pues no se habra ejecutado ninguna de las
asignaciones en las ramas de los condicionales. Puesto que la variable no tiene
valor, el llamado a Poner de la ultima lnea producira la destruccion del cabezal.

Actividad de Programacion 15

Escriba el codigo de AvisarEstadoDelCultivo en un programa, y pro-


barlo con tres celdas diferentes: una que contenga bolitas negras, una
que contenga bolitas azules pero no negras, y una que no contenga
bolitas ni negras ni azules. Observe lo que sucede en cada caso, y com-
pruebe que sucede cuando la variable no toma valor.

Una forma de corregir el error es darnos cuenta de que la accion de prender la luz
no siempre debe ejecutarse. En caso de que el cultivo no este ni azul ni negro,
no debe encenderse ninguna luz. Entonces podemos indicar la necesidad de
prender la luz con una nueva variable, esta vez de valor booleano. Esta variable
debe contener verdadero si la luz debe encenderse y falso en caso contrario.
procedure AvisarEstadoDelCultivo()
{-
PRECOND: ninguna, es una operacion total
-}
{
if (hayBolitas(Negro))
-- El cultivo se empezo a poner Negro

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


136

{
colorAEncender := Rojo
encenderLuz := True
-- Indicamos que hay que encender la luz de color rojo
}
else
{ if (hayBolitas(Azul))
-- El cultivo conserva su color Azul
{
colorAEncender := Verde
encenderLuz := True
-- Indicamos que hay que encender
-- la luz de color verde
}
else
{
encenderLuz := False
-- Indicamos que no hay que encender
-- la luz
}
}
IrAlOrigen()
if (encenderLuz)
{ Poner(colorAEncender) }
-- Encender la luz correspondiente,
-- si fue indicado
}

Podemos ver que el comando de encender la luz (el Poner del final) es ahora
condicional, y la condicion es el valor de la variable, que habra cambiado segun
el color del cultivo. Este codigo no produce la destruccion del cabezal (o sea, es
una operacion total).
Otra forma de provocar la autodestruccion mediante el uso de una variable
que no fue definida es utilizar dicha variable cuando la misma no tiene sentido,
por no corresponder con ningun valor. En G OBSTONES, la correspondencia en-
tre una variable y un valor sirve solamente dentro del procedimiento donde se
realiza la asignacion; o sea, cada procedimiento tiene sus propios recuerdos
que no comparte con ningun otro. La parte del codigo donde tal correspondencia
tiene sentido para una variable determinada se denomina alcance de la variable.
As, en G OBSTONES, las variables tienen alcance dentro de un procedimiento
exclusivamente.

Definicion 4.3.3. El alcance de una variable es la parte del codigo donde la


correspondencia entre la misma y un valor tiene sentido. En G OBSTONES todas
las variables tienen alcance solo dentro del procedimiento que las asigna.

El efecto de que el alcance de las variables sea entre procedimientos es que la


unica manera de comunicar informacion entre procedimientos sea a traves de los
parametros o de los valores de retorno de las funciones. O sea, no tiene sentido
utilizar en un procedimiento una variable asignada en otro. Cada procedimiento
posee su propia asignacion de variables a valores. Por ejemplo, el siguiente codi-
go es erroneo porque cada procedimiento tiene su propio espacio de variables, y
por lo tanto no comparten las variables.

procedimiento DuplicarRojasAlNorteMal()

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


137

{- PROPOSITO:
* ilustrar el uso INCORRECTO de variables
PRECONDICION:
* falla siempre, por invocar un procedimiento que
no puede tener exito
OBSERVACION:
* pretende mostrar lo que NO DEBE hacerse
-}
{
cantRojas := nroBolitas(Rojo)
Mover(Norte)
CompletarDuplicarRojasAlNorte()
}

procedimiento CompletarDuplicarRojasAlNorteMal()
{- PROPOSITO:
* ilustrar el uso INCORRECTO de variables
PRECONDICION:
* falla siempre, pues cant no es una variable definida,
ni un parametro
OBSERVACION:
* pretende mostrar lo que NO DEBE hacerse
-}
{
PonerN(cantRojas,Rojo)
-- cantRojas ES UNA VARIABLE SIN ASIGNAR!
-- (La asignacion de cantRojas en el otro
-- procedimiento no tiene validez en este)
}
La variable cantRojas asiganada con el numero de bolitas rojas en el procedi-
miento DuplicarRojasAlNorteMal, solo tiene alcance dentro del cuerpo de ese
procedimiento (o sea, solo tiene sentido utilizar dicha variable en ese procedi-
miento, y en ningun lugar mas). Por otra parte, el uso de cantRojas que se hace
en el procedimiento CompletarDuplicarRojasAlNorteMal es incorrecto, puesto
que no fue asignada ninguna variable con ese nombre. La forma correcta de co-
municar ambos procedimientos es utilizar un parametro, de la siguiente manera:
procedimiento DuplicarRojasAlNorteBien()
{- PROPOSITO:
* ilustrar el uso correcto de variables y parametros
PRECONDICION:
* debe haber una celda al norte
-}
{
cantRojas := nroBolitas(Rojo)
Mover(Norte)
CompletarDuplicarRojasAlNorteBien(cantRojas)
}

procedimiento CompletarDuplicarRojasAlNorteBien(cant)
{- PROPOSITO:
* ilustrar el uso correcto de variables y parametros
PRECONDICION:
* siempre funciona

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


138

-}
{
PonerN(cant,Rojo)
-- cant ES UN PARAMETRO!
}

Se puede observar que cantRojas se pasa como argumento al invocar el pro-


cedimiento CompletarDuplicarRojasAlNorteBien, y este lo utiliza mediante el
parametro cant.
Como se relacionan las variables con los parametros y los ndices? La res-
puesta a esta pregunta es que no se mezclan. O sea, si bien los parametros y
los ndices son identificadores al igual que las variables, no pueden ser asig-
nados. Entonces, no pueden existir, en un procedimiento dado, variables con el
mismo nombre que un parametro o un ndice. Si esto sucediese, se producira la
autodestruccion del cabezal.

procedure VariosErrores(color)
{- PROPOSITO:
* ilustrar la combinacion incorrecta de
parametros y variables y de ndices y variables
PRECONDICION:
* este codigo siempre produce la autodestruccion
-}
{
color := Negro -- color no puede ser una variable,
-- pues es un parametro
cantidad := 1
repeatWith cantidad in 1..5
-- cantidad no puede ser un ndice,
-- pues es una variable
{
PonerN(cantidad, color)
-- hace referencia a un ndice o a una variable?
}
}

Actividad de Programacion 16

Escribir el codigo del ejemplo anterior, y realizar cambios en los nombres


de las variables, parametro o ndices, hasta que ejecute correctamente.
Cual es el efecto de este procedimiento? Podra renombrar las varia-
bles de manera diferente para producir otro efecto distinto?

Leer con Atencion

G OBSTONES separa de manera clara las nociones de variable, parame-


tro e ndice. Esto es as con el objetivo de que resulte clara la distincion
entre las 3 ideas. Sin embargo, en otros lenguajes se utilizan los nom-
bres de maneras indistintas, ya sea para denotar parametros, variables
o ndices, y puede resulta confuso para quien no tiene las ideas claras.

Utilizando variables hay ciertas operaciones que son mas sencillas. En los proxi-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


139

mos ejemplos revisaremos algunas de las operaciones vistas en apartados o


unidades anteriores, para simplificarlas con el uso de variables.
El primero de los ejemplos a revisar es la funcion hayEnemigosCercaAlNorte
del subapartado 3.3.2. En dicho ejemplo, la funcion deba devolver un booleano
indicando si haba enemigos en alguna de las 3 celdas hacia el norte de la actual.
Para realizarlo, utilizamos el truco de codificar la existencia de enemigos con
bolitas azules en la celda actual y al terminar retornamos si haba o no bolitas
azules en dicha celda. Pero este ejercicio podra hacerse sin codificar con bolitas,
recordando si hay o no enemigos en una variable. El codigo sera:
function hayEnemigosCercaAlNorte()
{-
PROPOSITO:
* retorna verdadero si hay algun enemigo en las
proximas 3 celdas al Norte de la actual
PRECONDICION:
* hay 3 celdas lindantes al Norte
-}
{
hayEnemigos := False -- Al comienzo no sabemos si hay enemigos
repeatWith i in 1..3
{ if(hayEnemigosAlEnRango(Norte, i))
{ hayEnemigos := True } -- Si ve un enemigo, lo recuerda!
}
return(hayEnemigos) -- Se retorna el booleano recordado
}
Podemos observar como se hace innecesaria la codificacion con bolitas, gracias
a que el mecanismo de memoria provisto por las variables nos permite recordar
si en algun punto de las celdas controladas encontramos enemigos. Tambien
podemos observar en este ejemplo que la asignacion recuerda un valor fijo (por
ejemplo, en este caso, el False) hasta la siguiente asignacion, donde recuerda al
nuevo valor (en este caso, el True).

Actividad de Programacion 17

Realice los siguientes ejercicios, modificando adecuadamente los pro-


gramas que realizo antes. Pruebe si las nuevas versiones funcionan de
igual manera.

Ejercicio 4.3.2. Definir una funcion direccionDelEnemigo que cumpla el mismo


proposito que el procedimiento CodificarDireccionDelEnemigo del subaparta-
do 4.2.1 (o sea, indicar la direccion en la que se encuentra el enemigo), pero que
en lugar de codificarlo con bolitas, lo retorne como resultado.
Ayuda: considerar la utilizacion de una variable para recordar en que direc-
cion se encontro al enemigo, y luego retornar el valor de dicha variable.
Ejercicio 4.3.3. Reescribir el procedimiento MoverASiguienteSector, del ejem-
plo del sendero completado en el ejercicio 4.2.7, para utilizar variables en lugar de
codificar las direcciones con bolitas verdes. Probar nuevamente el procedimiento
PonerFloresEnSenderoSimple para asegurarse que el cambio fue correcto.
Ayuda: reemplazar CodificarDireccion(dir) por dirSectorSig := dir, y
luego reemplazar DecodificarDireccion() por un comando simple que utilice
dicha variable.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


140

Un punto de importancia con respecto a la asignacion es que la misma varia-


ble puede asignarse varias veces a valores diferentes, dentro del mismo pro-
cedimiento. La correspondencia entre la variable y un valor producida por cada
asignacion dura hasta que la siguiente asignacion es ejecutada. Esto hace que
la utilizacion de variables sea muy dependiente del orden de ejecucion. En el
proximo subapartado profundizaremos sobre este aspecto, al complementar la
herramienta de recorridos con la de variables.

4.3.2. Recorridos mas complejos


La idea de recorrido, presentada en el subapartado 4.2.3 se ve potenciada al
contar con la posibilidad de recordar informacion mediante el uso de variantes.
Utilizando variables, podemos definir la idea de recorrido de totalizacion o
recorrido de acumulacion, que recorre una secuencia de elementos, acumulando
el total de cierta informacion que cada elemento posee. Por ejemplo, si las celdas
del tablero representan a los productos de un changuito de supermercado, siendo
la cantidad de bolitas azules el precio a pagar por cada producto, y quisieramos
averiguar el precio total que deberemos pagar por la compra, podramos utilizar
el siguiente codigo, que hace uso de una variable libreta, donde llevamos la
cuenta:

function valorTotalDeLaCompra()
{
-- Iniciar el recorrido
libreta := 0 -- Preparar algo para llevar la cuenta
IrAlPrimerProducto() -- Ubicarse en el primer elemento

while (not finChango()) -- No se acabaron los productos


{
libreta := libreta + precioProducto()
-- Incorporar el precio actual a la
-- cuenta
PasarAlSiguienteProducto()
-- Pasar al siguiente
}

-- Finalizar el recorrido, informando el precio total


return (libreta)
}

La lnea mas interesante en este codigo es la de la asignacion dentro de la re-


peticion condicional. Puede considerarse como la idea de leer lo que tenemos
anotado en nuestra libreta, sumarle a eso el precio del producto que estamos
poniendo en el chango, y luego anotar el resultado nuevamente en la libreta.
Esta asignacion funciona incrementando el valor de la libreta con el precio del
producto actual, y entonces se la suele llamar un incremento de la variable. El
inicio de recorrido debe asegurarse que la variable exista, y como hasta el mo-
mento no se han visto productos, debe anotarse un 0 en la misma. Al terminar el
recorrido debe retornarse el valor anotado en la libreta, que sera el del total de
la suma de todos los productos en el chango. La operacion IrAlPrimerProducto
debe ir al origen, la operacion finChango debe verificar que el cabezal se en-
cuentra en la fila de mas arriba a la derecha (verificando que no se puede mover

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


141

(a). Tablero inicial (b). Tablero final

G.4.5. Prueba de la funcion valorTotalDeLaCompra

ni al Norte ni al Este), y la operacion PasarAlSiguienteProducto debe ser igual


a PasarASiguienteCelda, del final del subapartado 4.2.3.

Actividad de Programacion 18

Pase el codigo de la funcion valorTotalDeLaCompra, complete las ope-


raciones faltantes, y pruebe el codigo, colocando tantas bolitas negras
como el total de la compra en la celda del origen. Podra quedarle un
tablero como el del grafico G.4.5.

La idea de recorrido de totalizacion se puede utilizar para cualquier tipo de ele-


mentos, y para cualquier recorrido. Lo unico que precisa es inicializar una variable
con 0, y luego, al procesar cada elemento, agregar el valor de cada uno al total,
incrementando la variable en cuestion.

Actividad de Programacion 19

Realice los ejercicios 4.3.5 y 4.3.4, teniendo en cuenta en ambos casos


la idea de recorrido de totalizacion. Pruebe los programas resultantes.

Ejercicio 4.3.4. Definir una funcion distanciaALaBase que cuente y retorne el


numero de celdas que hay entre la celda actual y la base de la columna actual.
Pensar en estructurarlo como un recorrido de totalizacion, donde cada celda tiene
valor 1. Verificar que la cantidad retornada sea exactamente la pedida, pues es
comun retornar uno mas o uno menos que el valor solicitado.
Este error se denomina off-by-one
Ejercicio 4.3.5. Revisar la definicion de TotalizarFrecuenciaActual del ejerci- (en castellano se podra traducir co-
cio 3.4.2, para rehacerla como un recorrido de totalizacion sobre el valor de cada mo errado-en-uno), y proviene del
led. hecho de que el cabezal se mueve
menos veces de las que debe con-
Una variante del recorrido de totalizacion es la del recorrido que permite calcular tar.
el maximo o el mnimo de cierta cantidad. Para ello, se recuerda el maximo visto
hasta el momento en una variable, y al procesar cada elemento, se verifica si es
mayor que el maximo guardado, y en caso de serlo, se lo reemplaza.
Por ejemplo, para verificar de cual color hay mas bolitas en la celda actual, se
puede hacer un recorrido de calculo de maximo sobre colores.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


142

function colorConMasCantidad()
{-
PROPOSITO:
* retorna el color del que hay mas bolitas.
Si hay igual cantidad de mas de un color,
retorna el menor color posible
PRECOND:
* ninguna, es una operacion total
-}
{
-- Inicializar el recorrido
maxColor := minColor()
maxCant := nroBolitas(minColor())

-- Al recorrerse, puede usarse una repeticion indexada


-- si se conocen todos los elementos a recorrer!
repeatWith color in siguiente(minColor())..maxColor()
{
-- Procesar viendo si el actual es mayor
if (nroBolitas(color) > maxCant)
{
maxColor := color
maxCant := nroBolitas(color)
}
-- Pasar al siguiente esta implcito en el repeat!
}

-- Finalizar el recorrido, informando


return (maxColor)
}
Podemos observar varias cosas. La primera es que si conocemos todos los ele-
mentos a recorrer, puede utilizarse una repeticion indexada en lugar de una con-
dicional. La segunda es que procesamos por separado el primer color, pues es
necesario tener un valor inicial para el maximo posible. La tercera, y mas im-
portante para nuestro ejemplo de recorrido de calculo de maximo, es que son
necesarias 2 variables: una para recordar el maximo numero hasta el momento,
y otra para recordar a que color corresponda dicho numero.
Esta idea de recorrido puede aparecer en otras formas al calcular otros maxi-
mos. Por ejemplo, si queremos saber cual es el maximo numero de bolitas rojas
de una celda en la columna actual, usaramos un recorrido sobre la columna de
la siguiente manera:
function maxBolitasEnColumna()
{
-- Iniciar el recorrido
IrAlExtremo(Norte)
maxCantidad := nroBolitas(Rojo)

-- Falta procesar alguna celda?


while (puedeMover(Sur))
{
Mover(Sur)
if (nroBolitas(Rojo) > maxCantidad)
{

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


143

-- Si ahora hay mas, se reemplaza


-- el maximo recordado
maxCantidad := nroBolitas(Rojo)
}
}

-- Procesamos la ultima celda por separado,


-- al finalizar el recorrido
if (nroBolitas(Rojo) > maxCantidad)
{
-- Si ahora hay mas, se reemplaza el maximo recordado
maxCantidad := nroBolitas(Rojo)
}
return (maxCantidad) -- Se informa al terminar
}
Aqu podemos observar que como los elementos a recorrer son celdas, entonces
debemos usar una repeticion condicional, y puesto que la pregunta para seguir
es si se puede mover, el ultimo elemento debe procesarse por separado. Sin
embargo, el procesamiento del elemento actual sigue el mismo principio que en
el recorrido anterior, para calcular el maximo.
Finalmente, si en lugar de querer saber la cantidad, quisieramos saber de
que celda se trata (por ejemplo, para marcarla con bolitas de color Azul), de-
beramos recordar la cantidad de veces que nos movemos y usar ese numero al
terminar el recorrido.
procedure MarcarCeldaConMaxBolitasEnColumna()
{
-- Iniciar el recorrido
IrAlExtremo(Norte)
maxCantidad := nroBolitas(Rojo)
movimientosAlMax := 0
cantMovimientos := 0

-- Falta procesar alguna celda?


while (puedeMover(Sur))
{
Mover(Sur)
cantMovimientos := cantMovimientos + 1
if (nroBolitas(Rojo) > maxCantidad)
{
-- Si ahora hay mas, se reemplaza
-- el maximo recordado
maxCantidad := nroBolitas(Rojo)
movimientosAlMax := cantMovimientos
}
}

-- Procesamos la ultima celda por separado,


-- al finalizar el recorrido
if (nroBolitas(Rojo) > maxCantidad)
{
-- Si ahora hay mas, se reemplaza
-- el maximo recordado
maxCantidad := nroBolitas(Rojo)

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


144

movimientosAlMax := cantMovimientos
}
-- Y marcamos la celda que corresponde
IrAlExtremo(Norte)
MoverN(Sur, movimientosAlMax)
Poner(Azul)
}
En este codigo podemos observar como se utilizan 3 variables para recordar, por
un lado, la maxima cantidad de bolitas vistas hasta el momento (maxCantidad),
por otra parte, la cantidad de movimientos necesarios hasta donde fue vista di-
cha cantidad (movimientosAlMax, que es similar a recordar que color es el que
tena mas bolitas en el primer ejemplo), y finalmente, la cantidad de movimientos
hechos hasta el momento (cantMovimientos, necesaria para saber cuanto nos
movimos y poder recordarlo si es el maximo). Al finalizar el recorrido, en lugar de
informar la cantidad de movimientos, se realiza el marcado de la celda corres-
pondiente, con base en la cantidad calculada. Se debe observar que a diferencia
de un recorrido de busqueda, que finaliza apenas encuentra lo buscado, en este
caso deben procesarse todos los elementos, pues no se sabe de antemano cual
es el maximo.
Un recorrido para calcular el mnimo elemento de una secuencia es exac-
tamente igual en estructura a uno de calcular el maximo, solo que en lugar de
recordar el mayor, se recuerda el menor. Tener esto en cuenta al realizar los
siguientes ejercicios.

Actividad de Programacion 20

Realice los ejercicios 4.3.6 y 4.3.7, y pruebelos adecuadamente.

Ejercicio 4.3.6. Definir un procedimiento IndicarPuntoDebil que marque con


una bengala (representada con una bolita azul) la celda en la que el enemigo es
mas debil (haya menor cantidad de enemigos, representados con bolitas rojas).
Sugerencia: realizar un recorrido por celdas (similar al visto en la forma me-
jorada de BuscarInicioSendero), y durante este recorrido, recordar por sepa-
rado los movimientos al este y los movimientos al norte que debe hacer des-
de el origen para llegar a dicha celda (de manera similar a como se mostro en
MarcarCeldaConMaxBolitasEnColumna).
Ejercicio 4.3.7. Utilizando la representacion del display de un ecualizador del
ejercicio 3.4.2, realizar un procedimiento PosicionarseEnFrecuenciaMaxima que
ubique al cabezal en la base de la columna que tenga la frecuencia con mayor
intensidad.

Otra forma de recorrido donde la capacidad de recordar valores es fundamental


es cuando se debe recorrer una secuencia pero no se deben procesar todos los
elementos. Por ejemplo, imaginemos que queremos colocar una progresion de
bolitas verde en n celdas, tal que la cantidad de bolitas en cada celda sean solo
los multiplos de 2 o de 3 (o sea, 2, 3, 4, 6, 8, 9, 10, 12, etc.). Entonces, podra
usarse un recorrido con memoria de la siguiente manera
procedure ProgresionVerdeDosOTres(n)
{- PROPOSITO:
* armar una progresion de n celdas con cantidad de

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


145

bolitas que sea multiplo de 2 o de 3


PRECONDICION:
* que haya n celdas al Este
-}
{
-- Iniciar el recorrido
procesadas := 0 -- la cantidad de celdas ya tratadas
cantAColocar := 2 -- el inicio de la progresion

-- Mientras no se haya terminado el recorrido


while (procesadas < n)
{
-- Procesar el elemento actual
if (cantAColocar mod 2 == 0 -- multiplo de 2
|| cantAColocar mod 3 == 0) -- o multiplo de 3
{
PonerN(cantAColocar, Verde)
procesadas := procesadas + 1 -- se proceso una celda
Mover(Este) -- por eso pasa a la sig.
}

-- Pasar al siguiente numero a considerar


cantAColocar := cantAColocar + 1 -- probar un nuevo nro.
}

-- Finalizar el recorrido, volviendo al punto de partida


MoverN(Oeste, n)
}

Puede observarse como la pregunta para terminar de procesar responde a la


cantidad de celdas procesadas (que en este caso debe ser el parametro n), mien-
tras que el pasar a un nuevo elemento consiste en probar un nuevo numero. El
procesamiento de elementos consiste en verificar si el numero actual correspon-
de a una cantidad a poner, y en ese caso, ponerlo en la celda correspondien-
te. Variando el tratamiento de estos dos parametros se pueden lograr diferentes
combinaciones.

Actividad de Programacion 21

Realice el ejercicio 4.3.8, y verifquelo en el sendero del grafico G.4.3. En


el grafico G.4.6 pueden verse un par de invocaciones del procedimiento,
con parametros diferentes.

Ejercicio 4.3.8. Modificar el procedimiento PonerFloresEnSenderoSimple pre-


sentado en el subapartado 4.2.3, para que tome un parametro distancia, y co-
loque flores en el sendero separadas por la distancia dada.
Sugerencia: agregar una variable proximoSectorEn que cuente cuanto falta
para el proximo sector donde poner flores. Al procesar, si esta variables esta en
1, poner la flor y volver a poner la variable en la distancia maxima, y si no, decre-
mentar la variable.
Ayuda: tener en cuenta que el control de cual era el siguiente sector a mover
asuma que en el anterior ya se haba colocado una flor. Puesto que en esta va-
riante no se coloca una flor, debe marcarse un sector visitado reemplazando las

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


146

bolitas negras por bolitas verdes, para indicar que ya fue visitado. Si hiciese falta
volver a ponerlas negras, al finalizar el recorrido habra que hacer una subtarea
que vuelva a recorrer el sendero cambiando bolitas verdes por negras.

Actividad de Programacion 22

Realice el ejercicio 4.3.9, y pruebelo con el sendero del grafico G.4.3. El


resultado debera quedar como el grafico G.4.7.

Ejercicio 4.3.9. Modificar el procedimiento PonerFloresEnSenderoSimple del sub-


apartado 4.2.3 para que numere los sectores, colocando tantas flores en un
sector como la distancia de ese sector al inicio del sendero. O sea, en el inicio
debe colocar 1 flor, en el primer sector, 2 flores, en el tercero, 3 flores, etcetera.

Actividad de Programacion 23

Realice el ejercicio 4.3.10, y pruebelo en varias de las frecuencias del


ecualizador del grafico G.3.7a.

Ejercicio 4.3.10. Escribir un procedimiento IncrementarFrecuenciaActual, que,


teniendo en cuenta la representacion del ejercicio 3.4.2, incremente en uno la
frecuencia representada en la columna actual. Puede suponerse que la celda ac-
tual se encuentra en la base de la columna. Tener en cuenta que si la frecuencia
esta al maximo, no se incrementa, y que al incrementar, debe respetarse el color
de cada led.
Ayuda: estructurarlo como un recorrido sobre los 6 leds de la frecuencia,
incrementando una variable intensidad cada vez que se encuentra un led pren-
dido. El finalizar recorrido debe posicionarse sobre el led siguiente a la intensidad
(si esta es menor que 6), y encenderlo (ya sea verde o rojo, segun la posicion).

4.4. Ejercitacion
Este apartado culmina la introduccion al lenguaje G OBSTONES, con algunos ejer-
cicios avanzados que utilizan todas las herramientas vistas hasta el momento.

Actividad de Programacion 24

Realice los ejercicios de este apartado, y pruebelos en cada caso, sobre


los tableros adecuados.

Continuando con el juego de Procedrez que se describio en el apartado 3.4,


completamos los ejercicios que requeran herramientas avanzadas.
El procedimiento del ejercicio que se presenta a continuacion sigue la idea
del ejercicio 3.4.4, y fue utilizado en el ejercicio 3.4.5.

Ejercicio 4.4.1. Implementar el procedimiento MarcarMovimientosTorre, que re-


cibe un color col, y marca con una bolita de ese color cada uno de los poten-
ciales movimientos de la torre ubicada en la casilla actual. La precondicion del
procedimiento es que debe haber una torre en la casilla actual.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


147

(a). Tablero resultante de invocar al procedimiento


PonerFloresEnSenderoSimpleCada(4)

(b). Tablero resultante de invocar al procedimiento


PonerFloresEnSenderoSimpleCada(5)

G.4.6. Sendero simple con flores colocadas cada algunos sectores

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


148

G.4.7. Sendero simple numerado

Igual que en el caso del visir, deben marcarse las casillas ocupadas por piezas
del oponente, pero no las casillas ocupadas por piezas del mismo color. No se
deben marcar casillas saltando por sobre piezas propias ni del oponente.
El cabezal debe quedar ubicado en la casilla en la que estaba originalmente.

Se muestra un ejemplo para una torre negra en el grafico G.4.8a.


Ejercicio 4.4.2. Implementar el procedimiento MarcarMovimientosJugador que
recibe un color denominado jugador, y marca con una bolita de color Verde
cada uno de los potenciales movimientos de ese jugador. La precondicion es que
jugador debe ser Rojo o Negro.
Por ejemplo, si el jugador tiene un rey y una torre, marca con bolitas de color
Verde todos los potenciales movimientos del rey, y todos los potenciales movi-
mientos de la torre. Una casilla puede quedar marcada con varias bolitas, si hay
varias piezas que potencialmente puedan moverse all.

En el grafico G.4.8b se muestran todos los movimientos marcados del jugador


negro, que tiene un rey y dos torres. Observar que varias casillas reciben mas de
una amenaza.
Ejercicio 4.4.3. Implementar la funcion esMovimientoPosible, que devuelve un
booleano que indica si la pieza ubicada en la casilla actual podra moverse a la
casilla marcada como destino, indicada con una bolita de color Azul.
La precondicion de la funcion es que debe haber una pieza en la casilla actual,
que no debe haber casillas del tablero marcadas con bolitas de color Verde y que
exactamente una casilla del tablero debe estar marcada como destino (en todo
el tablero debe haber exactamente una bolita Azul).
Sugerencia: pensar en como reutilizar los procedimientos definidos en los
ejercicios anteriores.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


149

(a). Movimientos de la torre.

(b). Movimientos del jugador negro.

G.4.8. Movimientos de piezas del Procedrez

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


150

Leer con Atencion

De aqu en mas asumiremos siempre que el tablero es un juego valido


de Procedrez, o sea, que siempre hay exactamente un rey de cada color
en el tablero, que puede haber a lo sumo una casilla marcada como
destino (con una bolita Azul) y que no puede haber casillas marcadas
con bolitas de color Verde.

Ejercicio 4.4.4. Definir la funcion reyEnJaque que toma un parametro denomi-


nado jugadorDefensor que indica el color del jugador defensor ( Rojo o Negro), y
retorna si el rey del jugador defensor esta en jaque. Es decir, devuelve True si al-
guna pieza del jugador oponente podra moverse a la casilla donde se encuentra
el rey del jugador defensor. Devuelve Falseen caso contrario.
Ayuda: realizar un recorrido sobre las piezas del oponente, marcando al rey
defensor como destino.

Ejercicio 4.4.5. Definir el procedimiento MoverPieza que mueve la pieza ubicada


en la casilla actual a la casilla marcada como destino, sacando la bolita Azul del
destino. Si en dicha casilla hay una pieza del oponente, la captura.
La precondicion es que debe haber una pieza en la casilla actual, y exacta-
mente una casilla del tablero marcada como destino. Ademas, la casilla marcada
como destino debe ser un movimiento valido para la pieza que se esta moviendo.
Finalmente, la casilla marcada como destino debe estar vaca (sin piezas propias)
o con una pieza del oponente.

En el grafico G.4.9 se pueden ver dos momentos del movimiento de un visir


negro.
Ejercicio 4.4.6. Definir la funcion puedeMoverPiezaAlDestino, que indica si la
pieza ubicada en la casilla actual puede moverse a la casilla marcada como des-
tino sin que su rey quede en jaque. O sea, devuelve True si la condicion se
cumple, y False en caso contrario.
La precondicion es que debe haber una pieza en la casilla actual. Ademas,
debe haber exactamente una casilla del tablero marcada como destino.

Ejercicio 4.4.7. Definir la funcion puedeMoverAlgunaPiezaAlDestino que toma


un parametro jugadorDefensor ( Rojo o Negro) y retorna si el jugador defensor
dispone de alguna pieza que pueda moverse al destino sin que su rey quede en
jaque. En caso contrario, devuelve False.
La precondicion es que debe haber exactamente una casilla del tablero mar-
cada como destino.

El ultimo tema para presentar ejercicios se basa en una idea de Pablo Baren-
baum. Nuevamente agradecemos a Pablo por su generosidad.
La Piedra Rosetta es una losa del Antiguo Egipto que contiene inscripciones
del mismo texto en tres sistemas de escritura distintos: griego, egipcio demotico y
jeroglficos egipcios. En el siglo XIX, Jean-Francois Champollion se valio de esta
informacion para descifrar la escritura jeroglfica. Para auxiliarnos en el analisis
de lenguas muertas, haremos una version simplificada de este modelo.
El tablero de G OBSTONES se dividira en dos mitades, separadas por una co-
lumna marcada con bolitas negras en todas sus celdas. Las columnas de la mitad
izquierda representaran un texto de referencia. Las columnas de la mitad dere-
cha representaran un texto a descifrar. Notar que las mitades no necesariamente
tienen el mismo ancho.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


151

(a). El visir negro esta a punto de moverse a la casilla marcada como


destino.

(b). El visir negro se ha movido, capturando a la torre roja y dando as ja-


que al rey rojo.

G.4.9. Visir negro moviendose

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


152

Dentro de cada mitad, las bolitas azules representaran smbolos de un sis-


tema de escritura desconocido. Las bolitas rojas representaran smbolos de un
sistema de escritura conocido. Por ejemplo, nueve bolitas azules podran repre-
sentar un jeroglfico con forma de lechuza, y dos bolitas rojas la letra B.
En cada posicion del texto de referencia habra un smbolo desconocido, que
representa el texto original, y uno conocido, que representa su traduccion. En
cambio, cada posicion del texto a descifrar tendra solamente un smbolo desco-
nocido, que es lo que se quiere traducir.
Supondremos, de forma poco realista, que las traducciones se realizan smbo-
lo a smbolo, y que un smbolo se traduce siempre de la misma manera. Asumire-
mos tambien que todos los smbolos del texto a traducir ya figuran en el texto de
referencia. En ambas partes del texto puede haber espacios, que no se traducen
ni afectan la traduccion.
Ejercicio 4.4.8. Escribir el procedimiento DescifrarJeroglificos que comple-
te la traduccion del texto a descifrar.

Este ejercicio puede realizarse de tres maneras diferentes, cada una con su pro-
pia complejidad.
1. Recorrer primero el texto de referencia, recordando la traduccion de cada
smbolo (digamos, armando un diccionario), y despues recorrer el texto a
traducir, usando el diccionario ya armado.
Esta solucion es conceptualmente correcta, y en la siguiente Unidad se pre-
sentaran herramientas que permitiran estructurar la solucion de esta mane-
ra. Pero en G OBSTONES, con las herramientas vistas, esto no es factible,
porque solo se dispone de un numero finito de variables que recuerdan un
unico valor, y no se pueden usar para recordar un numero desconocido
de smbolos del alfabeto.
2. Recorrer el texto de referencia y, a medida que se encuentra un par cla-
ve/valor, traducir todas las ocurrencias de ese smbolo.
Esta solucion tiene la dificultad de que una vez visitado el texto a traducir,
hay que volver a la posicion del texto de referencia de donde haba par-
tido el cabezal. Esto puede hacerse dejando marcas sobre el tablero. Sin
embargo, esta solucion es compleja.
3. Esta posibilidad es la mas simple de programar (y quizas la mas natural en
algun sentido). La idea consiste en hacer una funcion traduccion que dado
un smbolo representado como un parametro de tipo numero que sera el
codigo del jeroglfico correspondiente, busque en el texto de referencia su
traduccion, devolviendo el codigo de la letra conocida correspondiente.
Hecho esto, el problema se puede resolver haciendo un unico recorrido
sobre el texto a traducir, traduciendo smbolo a smbolo mediante la funcion
recien definida. La ventaja es que no hay que preocuparse por dejar marcas
para volver, aprovechando que las funciones deshacen todos sus efectos.
La solucion mas simple del problema de la Piedra Rosetta muestra el poder que
tiene la division de un problema complejo en subtareas mas sencillas, siempre
que la descomposicion se haga pensando en simplificar el proceso completo.
Este, mas que ningun otro concepto, es el que deben llevarse de esta primera
parte de la introduccion a la programacion.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


153

Modularizacion

En las unidades anteriores hemos visto diferentes herramientas para expresar y


abstraer codigo en los programas de forma conveniente. En esta Unidad tratare-
mos otro conjunto de ideas y herramientas abstractas que nos permitiran agrupar
de cierta manera distintas partes de un programa.

5.1. Modulos
Hasta ahora, hemos aprendido que al programar es conveniente separar las
ideas en diversas tareas a resolver. Entonces, los programas en general estan
compuestos de distintas tareas que juntas dan lugar a un programa completo.
Ahora bien, cuando el numero de tareas y subtareas crece es importante man-
tener cierto orden, agrupando aquellas funciones o procedimientos que contribu-
yen a una tarea especfica, de manera tal de estructurar mejor a los programas
de forma global, para facilitar su comprension, su correccion y su modificacion.
Es facil observar que las aplicaciones tienen asociadas distintos objetivos que
deben cumplir, muchos de ellos independientes entre s. Por ejemplo, un proce-
sador de textos posee una region en la que podemos escribir y editar texto, pero
tambien tiene opciones para imprimir documentos, guardarlos en el disco duro,
enviarlos por mail, etcetera. Cada una de estas tareas podra ser codificada por
separado (por ejemplo, la opcion de imprimir y la de enviar mails seguramente no
dependan la una de la otra), por lo que comunmente en programacion se agru-
pa a estas distintas porciones de programas de cierta manera. Denominamos
modulo a un grupo de funciones y procedimientos que contribuyen a expresar la
solucion a determinada tarea.

Definicion 5.1.1. Un modulo es una coleccion de procedimientos y funciones


que implementara algunas de las tareas que debe realizar un programa completo.

De esta manera, podemos razonar a los programas como la union de varias par-
tes que interactuan entre s, los modulos, y que trabajan juntas para alcanzar
un objetivo comun, realizando cada una alguna de las tareas necesarias para la
consecucion de los objetivos finales del programa. Como dijimos, en esta Uni-
dad denominaremos modulo a cada una de esas partes en las que se encuentre
dividido un sistema. Cada modulo debera tener tareas bien definidas a cumplir
e idealmente sera independiente de otros modulos, o al menos debera comu-
nicarse de forma controlada con el resto. Observar que uno podra agrupar las
funciones y procedimientos de diversas maneras, pero no todas las divisiones
posibles daran como resultado una buena modularizacion, puesto que se espera

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


154

que cada modulo capture una tarea o idea general, y no que sean simples agru-
paciones de procedimientos. Por ejemplo, agrupar todos los procedimientos que
empiezan con la letra A en un modulo ModuloA, todos los que empiezan con B en
un modulo ModuloB, etc., no sera considerado una buena modularizacion, ya que
esta agrupacion no esta vinculada al problema a resolver, sino a los nombres de
los procedimientos. En cambio, una agrupacion de todos los procedimientos que
tengan que ver con imprimir en un modulo Impresion, y todos las de enviar mail
en un modulo Correo.
Para Reflexionar

La modularidad es una propiedad que no solo aparece en programa-


cion. Por ejemplo, en biologa los organismos tambien se descomponen
en modulos. As, la mitocondria forma parte de las celulas, y a su vez
estas forman organos, que finalmente dan lugar a un organismo com-
pleto. De la misma manera podra plantearse una analoga con los tex-
tos en lenguaje natural, a los que aplican coherencia y cohesion entre
parrafos definidos y enlazados por conectores (aunque siempre debe
destacarse que el lenguaje natural es menos estricto que los lenguajes
de programacion). Y en una empresa, tambien se da esta propiedad de
modularizacion? Pensar en la division departamental de una empresa.

Actividad 1

Dar otros ejemplos en los cuales se cumpla la propiedad de modularidad,


y describir la forma en la que se manifiestan los modulos en cada caso.

Adicionalmente pueden destacarse algunas caractersticas deseables de los modu-


los:

Los detalles de implementacion de un modulo no deberan compartirse con


otros modulos.

Cambios en la implementacion de un modulo no deberan afectar a usuarios


de dicho modulo.

El tamano de los modulos debera mantenerse acotado.

Los primeras dos caractersticas estan relacionadas con la interdependencia


modular, que hace que los programas sean modificables con mayor facilidad,
ademas de poder dividir el trabajo de programacion en equipos que desarrollan
distintos modulos en paralelo. De esta manera, a la implementacion podemos
verla como una caja cerrada con una ventana, la lista de que procedimientos y
funciones provee dicho modulo y que no deberamos saber como estan imple-
mentados. A las paredes de esta caja se las denomina barrera de abstraccion,
que es una forma de decir que quien usa un modulo no tiene permiso de saber
que pasa adentro, es decir, como las operaciones que provee el modulo estan
implementadas.
Por otro lado, un programador puede poseer distintos roles, dependiendo de
la tarea que lleve a cabo en relacion con un modulo:

Usuario del modulo


Solo puede invocar procedimientos y funciones que dicho modulo provee.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


155

Disenador del modulo


Define el conjunto de operaciones que posee el modulo.

Implementador del modulo


Es el encargado de implementar las operaciones definidas por el disenador.

La tarea del disenador es de las tareas mas difciles y los ejercicios de esta Uni-
dad siempre especificaran que operaciones deberan implementarse en determi-
nado modulo. El conjunto de operaciones que el disenador define para un modulo O sea, no se pedira que el estu-
se denomina interfaz del modulo. Por consiguiente, dicha interfaz tambien define diante asuma el rol de disenador.
la forma con la que podemos comunicarnos con dicho modulo. En esta Unidad,
usaremos la siguiente definicion de interfaz.

Definicion 5.1.2. Una interfaz es una lista de los nombres y tipos de las opera-
ciones provistas por un modulo.

Para Reflexionar

La idea de interfaz se encuentra presente en la vida cotidiana. Por ejem-


plo, para operar con un televisor utilizamos botones que permiten apro-
vechar distintas funcionalidades que el aparato posee: cambiar de canal,
subir o bajar el volumen, etcetera. En general, todo dispositivo posee una
interfaz con la cual podemos comunicarnos y as poder aprovechar sus
capacidades. Con los modulos de software ocurre lo mismo, solo que los
modulos proveen funcionalidades logicas y no fsicas.

5.2. P YTHON
Para programar utilizando los conceptos de esta Unidad dejaremos de utilizar
el lenguaje G OBSTONES, y utilizaremos un lenguaje de programacion llamado
P YTHON. A diferencia de G OBSTONES, que es un lenguaje pequeno, disenado
exclusivamente con la idea de presentar las primeras ideas de programacion,
P YTHON es un lenguaje de proposito general, lo que significa que es utilizado en
la vida real para resolver problemas de todo tipo, incluyendo aplicaciones como
las que utilizamos a diario. Esta es la razon por la que utilizaremos este lenguaje
en reemplazo de G OBSTONES. Si instalaron la herramienta P Y G OBSTONES, ya
tendran que tener instalado P YTHON. Utilizaremos la version en Windows de este
lenguaje, el cual trae un editor denominado IDLE. Para el resto de las unidades
siguientes tambien utilizaremos este lenguaje y este editor.
Lectura Obligatoria

Para aprender el manejo basico del editor de P YTHON mencionado con-


sultar el siguiente link.

.
https://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/IDLE_
spanish.html

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


156

G.5.1. Imagen de la carpeta Calculadora con visor

5.2.1. Como trabajaremos con P YTHON


Empezaremos con una serie de ejercicios que nos permitiran trasladar hacia P YT-
HON los conocimientos que adquirimos con G OBSTONES . Ademas, estos ejerci-
cios nos ayudaran a entender las diferencias de sintaxis entre ambos lenguajes.
Recordemos que la sintaxis es el La forma de trabajar sera la siguiente. A diferencia de los ejercicios programa-
conjunto de reglas estrictas, rgidas dos en G OBSTONES, que utilizaban un solo archivo para definir todo un programa,
que establecen que combinaciones
de herramientas del lenguaje es po-
en P YTHON un programa quedara definido por una serie de archivos, cada uno
sible expresar. siendo un modulo distinto de la aplicacion. Se pedira que cada ejercicio sea re-
suelto en una carpeta distinta, y existira un modulo que sera el principal, y que
debera llamarse Main. Dicho modulo se comunicara con los modulos restantes
de la aplicacion para integrarlos con el fin de resolver el problema pedido para
el ejercicio. Cabe aclarar que as como muchos procedimientos en G OBSTONES
podan ser reutilizados para ejercicios posteriores, lo mismo aplica para P YTHON
y los modulos que definamos.
Actividad de Programacion 2

Realice los ejercicios 5.2.1 y 5.2.2, que seran descrito paso a paso a
continuacion. Preste atencion a cada paso porque esta sera la forma de
trabajar con P YTHON en futuros ejercicios.

Ejercicio 5.2.1. Seguir las instrucciones dadas en los parrafos subsiguientes pa-
ra crear un programa Calculadora con visor.
Para ilustrar la explicacion anterior presentaremos un ejemplo que describa paso
por paso lo pedido para cada ejercicio. Este ejercicio de ejemplo consistira en
definir un modulo con las operaciones elementales de suma, resta y multiplica-
cion, que seran utilizadas por un modulo que imprimira una serie de resultados
por pantalla. Al programa completo lo denominaremos Calculadora con visor y
as tambien se nombrara a la carpeta que contenga a los modulos del programa
(como puede verse en el grafico G.5.1). Dentro de dicha carpeta crearemos dos
archivos, que se corresponden con los dos modulos requeridos para el programa:
Operaciones y Main (nunca olvidar a este ultimo). Puede observa2rse el conte-
nido resultante de la carpeta al crear estos archivos en el grafico G.5.2. Ambos
archivos tendran extension .py, la cual poseen todos los archivos fuente de un
Para esto debemos utilizar la he- programa P YTHON. No se alarme si P YTHON genera varios archivos mas dentro
rramienta IDLE que viene con P YT- de esa carpeta, adicionales a los del codigo fuente, ya que son creados cuando
HON . Se puede abrir desde el
menu de inicio, o utilizando el el programa se ejecuta por primera vez. Generalmente estos archivos poseen ex-
menu contextual. tension .pyc, pero tambien puede haber otros. Dentro del modulo Operaciones,
o sea, dentro del archivo Operaciones.py, colocaremos las siguientes definicio-
nes:
def sumar(x,y):
return x + y

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


157

G.5.2. Archivos de la carpeta Calculadora con visor

G.5.3. Editando el modulo Operaciones de la Calculadora con visor

def restar(x,y):
return x - y

def multiplicar(x,y):
return x * y
La regla de los cuatro espacios es
muy importante en P YTHON ya que
De estas tres funciones de P YTHON podemos comentar algunas diferencias con la indentacion es obligatoria (forma
la sintaxis que utilizabamos en G OBSTONES. Las palabras function y procedure parte de la sintaxis), siendo esta la
son reemplazadas por def. En P YTHON no hay distincion entre procedimientos forma de definir bloques en el len-
y funciones: todos los procedimientos pueden devolver valores a traves del co- guaje. Por dicho motivo debe res-
petarse esa cantidad exacta de es-
mando return. Una de las mayores diferencias con G OBSTONES es que en este pacios o se producira un error de
lenguaje los bloques de codigo no son encerrados entre llaves, sino que empie- sintaxis.
zan con : (dos puntos), y se indenta el codigo exactamente cuatro espacios
para indicar que el bloque pertenece a dicha definicion.
Si realizo correctamente lo indicado, debera tener una ventana como la que
se muestra en el grafico G.5.3.

A su vez, dentro del modulo Main, o sea dentro del archivo llamado Main.py,
colocaremos el siguiente codigo:
Si ya esta abierta la herramienta ID-
import Operaciones LE puede utilizar la opcion Nuevo
(New ) del menu Archivo (File ).
if __name__ == __main__:
resultado = Operaciones.sumar(4, 5)
print "4 + 5 =", resultado

En esta definicion nos detendremos en varios aspectos. La mayor diferencia a


observar es entre la definicion del procedimiento Main en G OBSTONES y la forma
en la que definimos a Main en P YTHON. La primera lnea luego de la de import in-
dica que el modulo actual representara el modulo principal de nuestro programa;
no es necesario entender dicha sentencia, solo utilizarla como la presentamos.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


158

G.5.4. Resultado de la ejecucion de la Calculadora con visor

El cuerpo de dicha alternativa condicional sera lo que se ejecutara como progra-


ma, de la misma forma que lo indicaba la definicion del procedimiento Main en
G OBSTONES. Por otra parte, la lnea import Operaciones indica que el modulo
actual utilizara operaciones de ese otro modulo.
La forma de utilizar una operacion definida en otro modulo, en este caso el
modulo Operaciones, es a traves de la denominada notacion puntual. Por eso la
La notacion puntual es muy uti- forma de llamar a la operacion sumar del modulo Operaciones es, por ejemplo,
lizada en programacion con dis- Operaciones.sumar(4,5).
tintos propositos, aunque general-
mente se utiliza para encadenar va-
Por otra parte, la asignacion de variables se denota como =, en contraste
rios elementos de forma consecu- con G OBSTONES que utilizaba el signo :=. Entonces el comando resultado =
tiva. En las siguientes unidades la Operaciones.sumar(4,5) denota la asignacion de la variable resultado con el
volveremos a utilizarla para fines si- numero resultante de invocar la operacion sumar del modulo Operaciones con
milares.
los argumentos 4 y 5.
Por ultimo, se utiliza un comando que imprime lo que el programador defina
a continuacion, el comando print. La coma se utiliza para separar valores entre
s, los que en la pantalla de impresion se visualizaran separados por un espacio.
As completamos la definicion del modulo Main que para este caso impri-
mira al ejecutarlo el resultado de sumar cuatro y cinco.
Ejercicio 5.2.2. Probar el programa Calculadora con visor definido en el ejercicio
anterior, ejecutandolo para obtener en la pantalla 4+5=9.
Para ejecutar un programa, desde la herramienta IDLE debe utilizar la opcion
Ejecutar modulo (Run Module (F5) ) del menu Ejecutar (Run ) o utilizar la
tecla F5. Debera obtener una salida como la que se muestra en el grafico G.5.4.
En suma, la metodologa empleada para los ejercicios de ejemplo (la creacion
de una carpeta, la separacion en diversos archivos, la utilizacion del comando
import y la manera de definir el modulo principal) tendra que ser tomada en
cuenta para los ejercicios pedidos a lo largo de esta unidad.

5.2.2. Herramientas abstractas en P YTHON


Dado que programaremos de ahora en mas en P YTHON, debemos conocer como
las herramientas abstractas que aparecan de una forma en G OBSTONES ahora
aparecen en este nuevo lenguaje: alternativa condicional, repeticion indexada,
repeticion condicional, asignacion de variables, procedimientos y funciones defi-
nidas por el usuario, y parametrizacion. Algunas de estas las hemos vislumbrado
en el ejercicio de ejemplo, pero detallaremos todas a fin de familiarizarnos con
la nueva sintaxis. Dado que el significado de cada construccion fue presentado
en Unidades anteriores, y en este nuevo lenguaje solo difiere la sintaxis, no nos
explayaremos demasiado en cada detalle de los ejemplos.
Asimismo, los smbolos usados para los operadores entre expresiones tam-
bien varan y estan sumarizados en la tabla T.5.2. Los operadores de igualdad y
comparacion son identicos a los de G OBSTONES y por eso no se encuentran en
el cuadro.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


159

Herramienta
G OBSTONES P YTHON
abstracta

if(puedeMover(Norte)) if puedeMover(Norte):
Alternativa { Mover(Norte) } Mover(Norte)
condicional else else:
{ Mover(Sur) } Mover(Sur)

Repeticion while(puedeMover(Norte)) while puedeMover(Norte):


condicional { Mover(Norte) } Mover(Norte)

# El ultimo valor del


# rango no es tenido
Repeticion repeatWith i in 1..4
# en cuenta
indexada { Poner(Rojo) }
for i in range(1,5):
Poner(Rojo)

case color of
if color == Rojo:
Rojo ->
FlorRosa()
{ FlorRosa() }
Alternativa elif color == Azul:
Azul ->
indexada FlorAzul()
{ FlorAzul() }
else:
_ ->
FlorComun()
{ FlorComun() }

T.5.1. Comparacion de sintaxis de herramientas abstractas

Con el fin de ejercitar la nueva sintaxis presentaremos una serie de programas


escritos en G OBSTONES que deberan ser transformados en programas P YTHON,
siguiendo las indicaciones dadas por la tabla anterior.
Actividad de Programacion 3

Transforme cada uno de los programas brindados en los ejercicios si-


guientes a la sintaxis de P YTHON.

Ejercicio 5.2.3. Transformar el siguiente programa:


procedure PonerVerdeSiHayRojaYAzul()
{
if (hayBolitas(Rojo) && hayBolitas(Azul))
{ Poner(Verde) }
}
Ejercicio 5.2.4. Transformar el siguiente programa:
procedure IrAlExtremo(dir)
{
while(puedeMover(dir))
{ Mover(dir) }

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


160

Nombre de operacion G OBSTONES P YTHON


Desigualdad /= !=
Conjuncion && and
Disyuncion || or

Asignacion de variables variableColor := Rojo variableColor = Rojo

T.5.2. Comparacion de sintaxis de operaciones basicas

procedure PintarColumna(color)
{
IrAlExtremo(Sur)
Poner(color)
while(puedeMover(Norte))
{ Mover(Norte); Poner(color) }
}

Ejercicio 5.2.5. Transformar el siguiente programa:

procedure PonerTodosLosColores()
{
colorActual := minColor()
Poner(colorActual)
colorActual := siguiente(colorActual)
while(colorActual == minColor())
{
Poner(colorActual)
colorActual := siguiente(colorActual)
}
}

5.3. Tipos abstractos de datos


Algunos lenguajes de programacion permiten seleccionar exactamente que ele-
mentos exporta un modulo (no es el caso del lenguaje P YTHON), permitiendo di-
senar de forma mas controlada la interfaz de los mismos. Esto vuelve explcita la
Al no permitir el acceso a operacio- barrera de abstraccion que el disenador del modulo escoja, con la que interactua
nes no exportadas, se limita el uso el usuario de ese modulo. Por otro lado, anteriormente presentamos a los tipos
de un modulo a las operaciones de
su interfaz (las operaciones expor-
de datos como conjuntos de valores y las operaciones correspondientes que apli-
tadas). can a estos. Si combinamos ambas ideas, es decir, definicion de un tipo de datos
y la barrera de abstraccion explcita dada por ocultamiento de elementos de un
modulo, estaremos definiendo lo que se conoce como tipo abstracto de dato (que
comunmente se conoce como TAD). De esta manera aprovecharemos todas las
ventajas que enumeramos sobre modularizacion, sobre todo interdependencia
modular y encapsulamiento (ocultamiento de informacion), para la definicion de
nuevos tipos de datos.
A modo de sntesis, un TAD queda definido por dos elementos:

Nombre del tipo de dato

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


161

Interfaz

En unidades anteriores hemos utilizado tipos de datos y operaciones sobre estos


(numeros, colores, direcciones, y sus operaciones como la suma de numeros o
la funcion siguiente sobre colores y direcciones), sin conocer como estas ope-
raciones estaban definidas o implementadas. Sin embargo, presentamos como
utilizarlas y pudimos codificar soluciones sin necesidad de saber su implemen-
tacion. La diferencia con estos tipos de datos y los definidos por programadores
es que los primeros son provistos por el lenguaje, mientras que los ultimos son
disenados por usuarios del lenguaje. Generalmente estos tipos de datos
Particularmente en P YTHON no es posible definir TADs, aunque el lenguaje se conocen con el nombre de tipos
primitivos de datos, junto con sus
provee otros mecanismos, que veremos en la proxima unidad, para poder definir respectivas operaciones primitivas.
nuevos tipos de datos con caractersticas de encapsulamiento y modularidad. Por
esta razon, la presentacion de TADs en esta Unidad no se extendera mas que en
su entendimiento teorico (que igualmente aporta lo pretendido para este curso).

5.4. Listas
Continuaremos el entendimiento de interfaces y tipos de datos con un tipo de
datos que ya viene definido en P YTHON; este tipo se denomina Lista. Este nuevo
tipo es distinto los que hemos utilizado con anterioridad ya que constituye lo que
se denomina una estructura de datos, que es una forma de organizar grupos de
datos de manera de garantizar formas de acceso eficientes a los mismos. Este concepto sera explorado so-
Las listas no son otra cosa que una coleccion o secuencia ordenada de ele- lo superficialmente en esta carpe-
ta de trabajo ya que generalmente
mentos de determinado tipo. Decimos que es una coleccion porque agrupa ele- existen asignaturas especializadas
mentos y los compone en un unico valor (por dicha razon las listas tambien son en cubrirlo en profundidad.
conocidas como un tipo compuesto de datos); y decimos secuencia ordenada
porque dicha composicion de datos posee un orden determinado, es decir, existe
un primer elemento seguido de un segundo, un tercero, un cuarto, etc., hasta lle-
gar al ultimo de la lista. A diferencia de otras estructuras, las listas pueden variar
la cantidad de elementos que poseen durante el transcurso del programa.
Para ilustrar esta idea, podemos imaginarnos una lista de numeros, o una
lista de colores, o una lista de personas, etcetera. P YTHON posee una notacion
comoda para describir listas. Utilizando numeros, un ejemplo es [1,2,3,4,5,6].
El siguiente procedimiento asigna la lista del ejemplo anterior a una variable y la
imprime por pantalla:

def imprimirListaEjemplo():
listaEjemplo = [1,2,3,4,5,6]
print listaEjemplo

Los tipos abstractos de datos se presentan dando el nombre del tipo de dato
y sus operaciones (su interfaz). Para cada tipo de datos, debe investigarse su
interfaz en la bibliografa correspondiente a cada lenguaje.
Lectura Obligatoria

El material de consulta para las operaciones sobre listas en P YTHON es

.
http://docs.python.org.ar/tutorial/datastructures.html#
mas-sobre-listas

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


162

5.4.1. Ejercicios con listas


Puesto que las listas son importantes en P YTHON, no sera necesario importar
ningun modulo, es decir, estan incluidas por defecto en el lenguaje. Para poner-
nos a punto con el uso de listas realizaremos una serie de ejercicios simples.
Actividad de Programacion 4

Realice cada uno de los siguientes ejercicios. Recuerde crear una carpe-
ta por cada ejercicio a resolver. Cada una de ellas contendra un archivo
Main sobre el que codificara la solucion.

Ejercicio 5.4.1. Escribir el siguiente programa P YTHON y visualizar el resultado


en pantalla:
if __name__ == __main__:
listaDePersonas = ["Jorge","Pepe","Esteban"]
print "La lista de personas es", listaDePersonas
Ejercicio 5.4.2. Agregar las personas "Fidel" y "Federico" al final de la lista
de personas del ejercicio 5.4.1 e imprimirlas por pantalla.
Ejercicio 5.4.3. Sobre la lista modificada del ejercicio 5.4.2, cambiar la impre-
sion en pantalla por print "Fidel esta en la lista?", listaDePersonas in
"Fidel". Debera visualizarse una respuesta afirmativa.
Ejercicio 5.4.4. Imprimir por pantalla el largo de la lista del ejercicio 5.4.2.
Observacion: debe investigarse en la lectura obligatoria consignada para po-
der completar este ejercicio (y los siguientes).
Ejercicio 5.4.5. Imprimir por pantalla la primer persona (i.e. "Jorge") de la lista
creada en el ejercicio 5.4.2, utilizando operaciones sobre listas.
Ejercicio 5.4.6. Crear una lista con las personas "Pepe" y "Jorge", obteniendo-
las de la lista de personas del ejercicio 5.4.2. Imprimir la lista obtenida por panta-
lla.

5.5. Diccionarios
Ademas de las listas, otra estructura de datos muy utilizada es lo que se conoce
como diccionario o mapping en ingles. Un diccionario es tambien una coleccion
de valores, pero en este caso de pares clave-valor (o sea, no habra un orden
preestablecido entre los elementos de la coleccion). Para cada clave existira un
valor asociado. Un ejemplo tradicional es el de asociar personas y numeros te-
lefonicos. En este caso el conjunto de claves son las personas que tiene cada
una asociada un numero telefono o una lista de todos sus numeros de telefonos.
Lectura Obligatoria

El material de consulta para las operaciones sobre diccionarios es P YT-


HON es

.
http://docs.python.org.ar/tutorial/datastructures.html#
diccionarios

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


163

5.5.1. Ejercicios con diccionarios

Los diccionarios tambien forman parte de P YTHON sin la necesidad de importar


un modulo particular. A continuacion realizaremos una serie de ejercicios practi-
cos para terminar de entender el proposito de esta estructura de datos.

Actividad de Programacion 5

Realice cada uno de los siguientes ejercicios. Recuerde crear una carpe-
ta por cada ejercicio a resolver. Cada una de ellas contendra un archivo
Main sobre el que codificara la solucion.

Ejercicio 5.5.1. Escribir el siguiente programa P YTHON y visualizar el resultado


en pantalla:

if __name__ == __main__:
agenda = {}
agenda["Jorge"] = 5552125
agenda["Pepe"] = 8885555
print "Mi agenda telefonica es", agenda

Ejercicio 5.5.2. Agregar las personas "Fidel" y "Federico" a la agenda te-


lefonica del ejercicio 5.5.1. El numero de "Fidel" debe ser 3332245 y el de
"Federico" debe ser 4445658. Ejecutar el programa para ver el resultado en
pantalla y verificar si fueron anadidas.

Ejercicio 5.5.3. Sobre el ejercicio 5.5.2 agregar lo necesario para imprimir por
pantalla solo el numero telefonico de "Fidel".

Ejercicio 5.5.4. Imprimir por pantalla la cantidad de personas que pertenecen a


la agenda.

Ejercicio 5.5.5. Eliminar de la agenda a "Pepe". Visualizar el resultado.

Ejercicio 5.5.6. Verificar si la persona "Roberto" se encuentra o no en la lista.

5.6. Iteracion sobre estructuras de datos

En P YTHON tambien es posible realizar una repeticion sobre todos los elemen-
tos de listas o diccionarios. Esta repeticion tambien es llamada iteracion sobre la
estructura. No es objetivo de esta carpeta profundizar sobre iteraciones en es-
te lenguaje, pero las veremos brevemente, porque sera requisito para resolver
algunos ejercicios que veremos mas adelante.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


164

Lectura Obligatoria

La informacion sobre este tema puede encontrarse en estos dos recur-


sos web.

.
http://docs.python.org.ar/tutorial/controlflow.html#
la-sentencia-for

.
http://docs.python.org.ar/tutorial/datastructures.html#
tecnicas-de-iteracion

5.7. Biblioteca P YGAME


En G OBSTONES la unica manera de poder visualizar el resultado de ejecutar un
programa era a traves del tablero. Dado que P YTHON es un lenguaje de proposito
general, no define una unica manera de poder visualizar los resultados de eje-
cutar un programa. Hasta el momento en los ejemplos que vimos imprimimos
valores por pantalla, pero dado que esto resulta poco didactico a largo plazo,
utilizaremos una biblioteca denominada P YGAME, que nos permitira ejercitar los
El termino biblioteca es una traduc- conceptos de esta unidad con mayor facilidad.
cion del ingles library. Una mala tra-
duccion al espanol, pero muy di- Definicion 5.7.1. Una biblioteca ( library en ingles) es un conjunto de modulos
fundida, es librera. Sin embargo, la destinados a resolver necesidades particulares en la codificacion de programas.
traduccion biblioteca es la correcta.
Por esta razon, las bibliotecas, a diferencia de los programas son utilizadas uni-
camente por programadores, es decir, no tienen por objetivo ser utilizadas por
usuarios no programadores.

P YGAME es una biblioteca destinada al desarrollo de aplicaciones multimedia


en P YTHON. Por ejemplo, permite programar juegos, editores de vdeo y audio,
etcetera. Los modulos que ofrece incluyen: un modulo para poder operar con
graficos en una ventana, otro para poder manipular sonidos y musica, otros para
comunicarnos con distintos dispositivos como teclado y mouse, entre los mas
http://www.pygame.org/tags/
game importantes que podemos mencionar. Para mas informacion es posible consultar
la documentacion oficial.
Actividad 6

http://www.pygame.org/docs/ Bajar e instalar P YGAME a partir del siguiente link

.
http://pygame.org/ftp/pygame-1.9.1.win32-py2.7.msi

Empezaremos con una serie de ejercicios con el fin de conocer gradualmente el


manejo de algunos de los modulos de P YGAME. Para comenzar debemos impor-
tar el modulo principal que ofrece esta biblioteca. La mayora de los ejercicios que
realicemos con P YGAME en esta Unidad tendran la siguiente estructura basica:

import pygame

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


165

import sys

def screenSize():
return (320,240)

def Game():
pygame.init()
screen = pygame.display.set_mode(screenSize())
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill((255,255,255))
drawGame(screen)
pygame.display.flip()
tick = clock.tick(60)

if __name__ == "__main__":
Game()

No es necesario entender cada lnea de codigo, y en cada ejercicio solamente


nos remitiremos a definir el procedimiento drawGame que recibe la pantalla por
parametro. Esto nos permitira pasar como argumento a la pantalla para los dis-
tintos procedimientos de dibujado. Dichos procedimientos se encuentran en el
modulo Draw de la biblioteca.
A modo de ejemplo, la siguiente definicion de drawGame dibuja un crculo en
el centro de la pantalla:

def drawGame(surface):
(x,y) = screenSize()
pygame.draw.circle(surface, (0,255,0), (x/2,y/2), 100, 2)

El resultado de ejecutarlo es el siguiente:

Este formato es conocido en aplica-


ciones graficas. Generalmente ca-
da valor en este formato se pre-
senta como una terna que posee
como primera componente la can-
tidad de rojo, la segunda, de ver-
de y la tercera, de azul. Los valores
Es interesante entender la definicion de drawGame de este ejemplo. Comienza de cada color varan de 0 a 255. El
asignando respectivamente a un par de variables x e y las componentes de an- valor (255,255,255) es el blanco, y
cho y alto de la pantalla (definidas a traves de una funcion en el modulo Main). el valor (0,0,0) constituye el negro.
A continuacion se invoca el procedimiento circle del modulo draw de P YGAME. Para mas informacion consultar
Dicho procedimiento recibe una serie de argumentos. El primero, como suce-
dera con todos los procedimientos de dibujado del modulo draw, es la superficie
sobre la que se dibujara la figura, que en este programa sera la pantalla (recibida http://es.wikipedia.org/wiki/
Modelo_de_color_RGB
como parametro en surface). Luego recibe una terna de numeros enteros, que
constituye un color en formato RGB. Los tres argumentos restantes constituyen

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


166

respectivamente la posicion, el tamano del radio y el grosor de la circunferencia.


Todas las medidas son en pxeles.

Lectura Obligatoria

Para una descripcion detallada de cada procedimiento del modulo draw


leer la documentacion oficial.

www.pygame.org/docs/ref/draw.html

Actividad de Programacion 7

A continuacion realizaremos algunos ejercicios simples con P YGAME con


el objetivo de acostumbrarnos a la tarea de seleccionar procedimientos
de distintos modulos para resolver problemas.

Ejercicio 5.7.1. Utilizando el procedimiento line, que toma una superficie, un


color, una posicion inicial y una posicion final, dibujar un cuadrado de lado 3.
Dicho procedimiento se encuentra en el modulo draw de P YGAME. Observacion:
debe buscarse el procedimiento adecuado, utilizando la documentacion.

Ejercicio 5.7.2. Con base en lo aprendido hasta ahora sobre procedimientos pa-
ra dibujar crculos, colecciones e iteradores, definir un procedimiento denomina-
do DibujarCirculosEn que reciba una lista de pares de coordenadas y dibuje
crculos de radio 3 con centro en cada una de dichas coordenadas.

5.8. Ejercicio integrador

Habiendo finalizado la presentacion de todos lo conceptos de esta unidad, pa-


saremos a programar el juego S OKOBAN. Este juego ha sido elegido por poseer
Para una descripcion mas deta- caractersticas que nos permitiran ejercitar conceptos tanto en esta unidad como
llada del juego puede consultarse de unidades anteriores.

El S OKOBAN es un juego de ingenio en el que un personaje (generalmente


caracterizado como un operario de fabrica, pero en este caso un robot) empuja
http://en.wikipedia.org/wiki/ cajas alrededor de un mapa que contiene paredes que delimitan la movilidad
Sokoban
de los objetos dentro de el. El objetivo es ubicar las cajas dentro del mapa en
distintos puntos, que podramos considerar como huecos en donde ubicarlas, de
tal manera que cada caja se corresponda con cada hueco. Las cajas ademas solo
pueden ser empujadas; o sea, no se puede tirar de ellas en sentido contrario, por
lo que si una caja queda ubicada contra una pared no podremos separarla de la
misma.
En el grafico G.5.5 podemos visualizar un tpico nivel del juego que codifica-
remos. Los objetivos son marcados como puntos rosa en el mapa. Cuando una
caja se encuentre en uno de los puntos objetivo se vera mas palida que lo nor-
mal. En este ejemplo una de las cajas ya se encuentra ubicada en uno de estos
puntos y el jugador debera proceder a ubicar la restante en el punto rosa.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


167

G.5.5. Ilustracion del Sokoban

5.8.1. Organizacion del proyecto

Comenzaremos dando una descripcion detallada de los modulos de este proyec-


to. Como hemos expresado en esta unidad todo proyecto de software se organiza
en distintos componentes de alguna manera, que al combinarse formaran el pro-
ducto final.
En la codificacion de juegos generalmente se observan al menos dos grupos
de modulos bien diferenciados. Uno contendra aquellos modulos que contengan
la logica que posee el juego, incluyendo todas sus reglas, objetos que lo consti-
tuyen, etcetera. El otro grupo suministrara una interfaz grafica que permita a los
usuarios justamente poder jugar a dicho juego, e interactuar con la logica del Una interfaz grafica se constituye
mismo. Este ultimo grupo, por ende, hace uso de los modulos del primer grupo. por el conjunto de elementos visua-
les que aparecen en pantalla pa-
Pero lo que debemos destacar es que los modulos de logica no utilizan ningun ra que el usuario pueda interactuar
procedimiento o funcion que deba pertenecer a los modulos multimedia. Esto se con el programa. No tiene relacion
conoce como separacion de incumbencias del ingles separation of concerns. alguna con la interfaz de los modu-
los que trabajamos en la Unidad
anterior.
Para Ampliar

El concepto de separacion de incumbencias no sera cubierto en profun-


didad en esta unidad. Para obtener mas informacion puede consultarse

http://en.wikipedia.org/wiki/Separation_of_concerns

Dado que S OKOBAN es un juego, mantendremos esta separacion de incumben-


cias. En la tabla T.5.3 puede observarse la distribucion de modulos junto con sus
incumbencias. Ademas existen dos tipos de modulos adicionales a los ya men-
cionados de logica e interfaz grafica. Uno de estos modulos es de manejo de
recursos, ya que el juego utiliza imagenes para representar objetos y este modu-
lo provee procedimientos que permiten manipular dichas imagenes. Y el otro tipo
adicional de modulos son los llamados auxiliares, que no entran en ninguna de
las otras categoras dado que generalmente los juegos tambien poseen valores
de configuracion inicial (tamano que ocupa el juego en pantalla, por ejemplo) u
otros procedimientos de uso general no necesariamente vinculados con ninguna
de las incumbencias especficas del juego. Por ultimo, como en todo proyecto,
existe un modulo que sera el que inicie la aplicacion, en este caso Main.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


168

Incumbencia Modulos

Level
Logica del juego
SokobanLogic

Manejo de Recursos Resources

Dibujado en Pantalla SokobanDrawing

Aplicacion Main

Common
Auxiliares
Constants

T.5.3. Distribucion de modulos del S OKOBAN

5.8.2. Implementacion del juego


Para realizar esta implementacion, nosotros proveeremos todos los modulos com-
pletamente codificados, excepto SokobanDrawing y SokobanLogic. Estos dos ulti-
mos carecen de la implementacion de muchos de sus procedimientos y funcio-
nes, por lo que la tarea de este subapartado es definirlas para completar la codi-
ficacion del juego. Pero antes de pasar a definir esto, debemos describir detalla-
damente lo que ya se encuentra implementado.
En la implementacion existen varios tipos de objetos en el juego: cajas ya
ubicadas en sus posiciones-objetivo, cajas aun no ubicadas, objetivos, paredes
y, por supuesto, el personaje. Cada uno es representado con un codigo unico
retornado por diversas funciones que nos permitiran representar el tipo de objeto
dentro del juego. Para las cajas sin ubicar la funcion es BOX(), para las cajas
ubicadas es DARKBOX(), para los objetivos del mapa es GOAL(), para las paredes
es WALL() y para el personaje es PLAYER().
Por su parte, existen dos diccionarios importantes: el de recursos, denomi-
nada por ejemplo resources, que contiene la imagen para cada tipo de objeto
del juego, y el de coordenadas, denominada por ejemplo coordMap, que contie-
ne listas de coordenadas para cada tipo de objeto del juego. La lista coordMap
representa todas las coordenadas del mapa sobre las que se debe pintar un
objeto del juego. Por ejemplo, las paredes, si bien estan representadas por un
unico dibujo, aparecen en muchos de los sectores del mapa; y coordMap con-
tiene, asociadas al objeto WALL(), todas las coordenadas sobre las que deben
dibujarse dichas paredes. Entonces, a modo de ejemplo, si deseamos extraer la
imagen del personaje escribimos resources[PLAYER()] y eso resultara en ob-
Recordemos que esta notacion es tener dicho recurso. Del mismo modo si queremos obtener la lista coordenadas
la que corresponde a obtener el va- para las paredes escribimos coordMap[WALL()]. Estos diccionarios se recibiran
lor asociado a una clave determina-
da en un diccionario.
siempre como parametro, por lo que su nombre puede variar, aunque dentro del
enunciado de cada ejercicio sera convenientemente explicitado; generalmente el
nombre de parametro para el diccionario de coordenadas sera coordMap y para el
diccionario de recursos sera resources, aunque no siempre tiene que ser nece-
sariamente as, ya que aprendimos que los nombres de los parametros pueden

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


169

variar segun el gusto y el estilo de cada programador.


Actividad de Programacion 8

Implemente todas las definiciones faltantes para completar la codifica-


cion del juego de S OKOBAN, siguiendo la gua dada en los ejercicios
enunciados a continuacion. Coloque cada una en el modulo que le re-
sulte apropiado. Al terminar con todas, compruebe si el juego funciona
segun lo esperado.

Ejercicio 5.8.1. Implementar el procedimiento drawObjectInCoords. Este pro-


cedimiento toma 3 parametros: la pantalla sobre la que dibujar, el objeto a pintar
y una lista de coordenadas sobre las que tendra que pintar ese objeto.
Para pintar un unico objeto en una cierta coordenada utilizar el procedimiento
drawObjectInCoord, que ya viene definido. Dicho procedimiento recibe tambien 3
parametros: la pantalla, el objeto y un par de coordenadas sobre las que pintara.
Lo que debe hacerse es recorrer la lista de todas las coordenadas sobre las
que pintar el objeto y, utilizando drawObjectInCoord, pintarlo sobre cada una de
las coordenadas provistas por esa lista.
Ejercicio 5.8.2. Implementar el procedimiento drawAllObjects. Este procedi-
miento dibuja todos los objetos del juego por pantalla. Para esto recibe 3 parame-
tros: la pantalla, el diccionario de recursos y el diccionario de coordenadas para
cada objeto.
En primer lugar debe obtenerse la lista de todos los posibles tipos de obje-
tos del juego utilizando la funcion resourceNames(). Luego debe recorrerse esa
lista y para cada uno de los tipos de objetos, encontrar su imagen y la lista de
coordenadas extrayendo esa informacion de los diccionarios respectivos.
Con ambos elementos obtenidos, debe utilizarse como subtarea el procedi-
miento drawObjectInCoords definido con anterioridad, para poder pintar para un
tipo de objeto todas sus apariciones en el mapa segun la lista de coordenadas
sobre las que pintar.

Ejercicio 5.8.3. Implementar la funcion moveWorker. Este procedimiento recibe


dos parametros: la posicion actual del jugador y la direccion hacia la que desea
moverse, y retorna la nueva posicion en la que debera terminar el personaje.
Para realizar esta tarea ya estan implementados los siguientes procedimien-
tos: moveWorkerDown, moveWorkerUp, moveWorkterLeft y moverWorkerRight. To-
dos reciben como parametro una posicion y retornan la nueva posicion a la que
debera ser trasladado el personaje.
Para distinguir los casos de las direcciones se poseen las funciones DOWN(),
UP(), LEFT(), RIGHT(). Por ejemplo, para preguntar si la direccion es hacia abajo
puede escribirse dir == DOWN().

Ejercicio 5.8.4. Implementar el procedimiento addNewBox. Este procedimiento


recibe dos parametros: el mapa de coordenadas de los objetos del juego y la
coordenada en la que se encontrara esta nueva caja que se quiere anadir.
Debe realizarse una pregunta utilizando la funcion isAGoal, que verifica si
una caja se encuentra o no en un punto de objetivo, y para ello recibe como
parametro el mapa de coordenadas y la coordenada de la caja.
Si el lugar donde se anade la caja es un punto objetivo, debera agregar su
coordenada a la lista de coordenadas del tipo de objeto DARKBOX(); de lo con-
trario, la coordenada corresponde a una caja comun, del tipo BOX() y debe ser
agregada en la lista correspondiente.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


170

Ejercicio 5.8.5. Implementar la funcion collideWith que recibe el mapa de coor-


denadas, un tipo de objeto y una coordenada, y verifica en el mapa de coor-
denadas si la coordenada recibida es alguna de las coordenadas posibles que
aparecen para el tipo de objeto recibido.
Por ejemplo, collideWith(coordMap, WALL(), coord) verifica si la coorde-
nada coord forma parte de las paredes del juego.

Ejercicio 5.8.6. Implementar la funcion isAGoal que dado el mapa de coorde-


nadas y una coordenada, verifique si esa coordenada pertenece a la lista de
coordenadas de los puntos objetivos.
Para esto utilizar la subtarea collideWith. Debe recordarse que el tipo de
objeto que representa a los puntos objetivos es GOAL().

Ejercicio 5.8.7. Implementar la funcion canChageBoxPos que dado el mapa de


coordenadas y una coordenada, verifique si una caja puede moverse a dicha
coordenada dentro del juego.
Una caja puede moverse si se dan dos condiciones: no colisiona con una
pared y no colisiona con otra caja. Recuerde que siempre hay dos tipos de cajas,
las que estan ubicadas sobre un punto objetivo y las que no, por lo que debe
verificarse que la caja dada no colisione con ninguna de ellas.
Puede utilizarse la funcion collideWith para implementar esta funcion.

Ejercicio 5.8.8. Implementar la funcion winGame que verifica si el juego fue ga-
nado.
Para esto, winGame verifica que la lista de cajas a colocar (que no estan sobre
objetivos) no se encuentre vaca, recibiendo por parametro dicha lista de coorde-
nadas. Para verificar si una lista posee o no elementos puede preguntar si posee
exactamente cero elementos.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


171

Programacion orientada a objetos

Dentro de la disciplina que es la programacion existen distintos paradigmas de


programacion. Cada paradigma representa un enfoque particular sobre como
abordar el desarrollo de los programas. Hasta ahora estuvimos operando con
lo que se conoce como programacion procedural (o estructurada), es decir, a
los programas concebidos como una serie de definiciones de procedimientos y
funciones que pueden o no ser divididos en distintos modulos. En esta Unidad
presentaremos otro paradigma, conocido como programacion orientada a obje-
tos.

6.1. El paradigma de orientacion a objetos


La programacion orientada a objetos esta relacionada con la unidad 5, ya que
una de sus mayores caractersticas es proveer mecanismos de encapsulamiento
de informacion. El paradigma provee, principalmente, una serie de metaforas que
permiten abordar la programacion desde un enfoque distinto. En este paradigma Algunas de las ideas capturadas
los programas son entendidos como un intercambio de mensajes entre objetos. por estas metaforas han sido pre-
sentadas en unidades anteriores.
Con cada mensaje que un objeto puede recibir se relaciona un metodo, que no En esta unidad son vistas desde
es mas que un procedimiento que ese objeto define, pero con la caracterstica otro angulo.
adicional de que siempre devuelven un valor. O sea, los metodos combinan la
idea de procedimiento y de funcion en una sola pieza de codigo.
La recepcion de un mensaje por un objeto se vincula a la ejecucion de un
metodo. La interaccion entre los objetos mediante el envo de mensaje forman
un programa. Esto conlleva una forma particular de razonar los programas, dis-
tinta a concebirlos solamente como una coleccion de procedimientos o funciones.
Si bien el programador codifica procedimientos y funciones (en la forma de meto-
dos), ahora estos perteneceran a un determinado objeto, que es mas que un
simple modulo. Al igual que los modulos, los objetos poseen una interfaz, pe-
ro a diferencia de ellos, poseen ademas un estado interno y una identidad Las
diferencias entre ambos enfoques estan sumarizadas en la tabla T.6.1.
Al hablar de objetos debemos considerar una serie de nociones o ideas que
nombran y ordenan la forma de trabajar con objetos. Por ello, comenzaremos con
una serie de definiciones, que luego se iran ejemplificando a lo largo de la Unidad.
Muchas de estas nociones aparecen en todos los lenguajes con orientacion a
objetos, y otras aparecen solo en algunos de ellos. Es importante tener una idea
general de las nociones mas importantes del paradigma, para poder aprender
cualquier lenguaje con objetos.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


172

Modulos Objetos
Para ejecutar un procedimiento de Los objetos deben ser instanciados
un modulo basta con saber el nom- para poder recibir mensajes.
bre del modulo y el nombre del pro-
cedimiento.

Los modulos definen colecciones Los objetos definen ademas atribu-


de procedimientos y funciones. tos que representan el estado in-
terno del objeto.
Los modulos no poseen identidad. Cada objeto posee su identidad
que lo diferencia de otros objetos.

T.6.1. Cuadro comparativo entre modulos y objetos

Para Ampliar

Estas ideas se estudiaron en primer lugar en un lenguaje llamado S MA -


LLTALK , que fue el primer lenguaje con objetos. Puede resultar interesan-
te profundizar sobre el surgimiento de las mismas. En el artculo siguien-
te pueden encontrarse las ideas con las cuales fue disenado S MALLTALK.
Recurso Web

http://www.cs.virginia.edu/~evans/cs655/readings/
smalltalk.html

Definicion 6.1.1. Un objeto se compone de una coleccion de metodos, que es-


tablecen los mensajes que este puede recibir (su interfaz) y de atributos, que
establecen el estado interno del objeto. Todo objeto ademas posee como atribu-
to una identidad unica que lo distingue del resto.

Definicion 6.1.2. El estado interno de un objeto esta constitudo por el grupo de


atributos que el objeto define y que tienen un valor determinado en cada momen-
to de la existencia del objeto.

En algunos lenguajes el estado del objeto es privado y otros objetos no pueden


conocerlo de forma directa; en otros, cualquiera puede conocer el estado interno
de un objeto.

Definicion 6.1.3. Una propiedad o atributo de un objeto es una caracterstica


que el objeto posee, que forma parte de su estado.

Definicion 6.1.4. La interfaz de un objeto se define por el conjunto de mensajes


La nocion de operaciones ocultas
que el objeto puede recibir, y se corresponde con el conjunto de metodos que
en un tipo abstracto produce un implementa cada objeto.
efecto similar en los modulos: no es
lo mismo acceder a un modulo des- Un concepto interesante de un objeto es que puede ofrecer diferentes interfaces
de afuera de su barrera de abstrac-
cion que desde dentro (el conjunto
en diferentes contextos. Esto vara de lenguaje en lenguaje, siendo lo menos res-
de operaciones utilizables es dife- trictivo que la interfaz sea la misma para todos los demas objetos. Sin embargo,
rente). en la mayora de los lenguajes, cuando se busca conocer la interfaz de un objeto
debe indicarse tambien en que contexto se usara.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


173

Definicion 6.1.5. Un metodo es la implementacion de un mensaje que el obje-


to puede recibir. Es comparable con la nocion de procedimiento, pero ademas
devuelve valores como una funcion.
Definicion 6.1.6. La identidad de un objeto es una caracterstica perteneciente
a cada objeto, que permite diferenciarlo unvocamente del resto.
Dos objetos con diferente identidad pueden tener exactamente los mismos atri-
butos, y sin embargo, seran diferentes. Puesto que los atributos de un objeto
pueden variar con el tiempo, en algun momento uno de los dos objetos puede
cambiar y el otro no; esto es posible gracias a la identidad que poseen.
Al pensar con objetos, resulta util imaginar que cada objeto posee incum-
bencias o responsabilidades inherentes a el. Estas responsabilidades definen
que problemas resuelve exactamente dicho objeto. Sobre esta carectarstica se
razonan dos propiedades deseables para todo objeto, que son cohesion y aco-
plamiento. Se dice que un objeto es cohesivo si sus responsabilidades son mni-
mas, es decir, no resuelve mas de lo que le compete. Por otro lado, es deseable
que un objeto posea bajo acoplamiento con otros objetos, lo que significa que es De la misma manera que un pro-
deseable que un objeto dependa lo menos posible de las caractersticas internas cedimiento debe intentar cumplir
exactamente sus objetivos y no ha-
de otros objetos. Esto ultimo tiene que ver con lo discutido en la unidad anterior cer cosas de mas.
acerca de la modularizacion de la informacion. Garantizar estas dos propieda-
des no siempre es facil en la codificacion dentro de este paradigma, aunque son
objetivos a conseguir.
Para Reflexionar

Son contrastables las nociones de cohesion y acoplamiento con la idea


de separacion de incumbencias discutida en la unidad anterior? Por
que?

Definicion 6.1.7. La responsabilidad es una nocion acerca de los objetos que


ayuda a razonar que comportamiento sera coherente que el objeto defina. Esto
repercutira en la interfaz que se defina para el objeto.
Definicion 6.1.8. La cohesion indica en que medida un objeto respeta su res-
ponsabilidad.
Definicion 6.1.9. El acomplamiento de un objeto define el grado de dependen-
cia de un objeto con respecto a otros objetos, o sea, si depende o no de las
caractersticas especficas de otros objetos o solo de sus interfaces.

Ejemplo

Razonemos acerca de la representacion de un auto como un objeto


de este paradigma. Un auto puede poseer atributos tal como nivel de
combustible en el tanque, velocidad maxima, velocidad actual, color de
carcaza, etcetera. A su vez, un auto posee comportamiento inherente
a s mismo, como pueden ser arrancar, llenar su tanque, acelerar, fre-
nar, etcetera. Esta podra ser la responsabilidad de este objeto. Este es
un ejemplo de como razonar acerca del modelado de una entidad de
la realidad en forma de objeto: razonamos acerca de las atributos que
deseamos que posea y que comportamiento estara ligado al objeto. No
obstante, en la mayora de los casos no implementaremos objetos del
mundo real sino que programaremos en forma de objetos la especifica-
cion de ejercicios, tal como hicimos hasta el momento.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


174

Por ultimo debemos presentar una idea que, si bien no forma parte de todos
los lenguajes orientados a objetos, forma parte de la mayora de ellos, y en es-
pecial de P YTHON, que es el lenguaje que utilizaremos en esta Unidad. Esta idea
es la de clase, que es la definicion de la estructura sobre la que se creara un gru-
po de objetos particulares. Por ejemplo, para poder crear muchos objetos con las
mismas caractersticas definiremos la clase de un automovil, que definira que ca-
ractersticas tendra cada automovil particular, es decir, sus atributos y metodos
(pero no los valores especficos de cada atributo, los cuales dependeran de cada
objeto en s y de su identidad).
En las primeras unidades hemos visto que cada expresion tena un tipo. En
el paradigma de objetos utilizamos de manera similar la idea de clase. Particular-
mente (al menos en los lenguajes orientados a objetos que poseen clases, que
son mayora) nos interesa saber a que clase pertence cada objeto. Por ello, una
nocion adicional al comportamiento, identidad y estado interno de un objeto, es
la clase del mismo.
Leer con Atencion

A modo de resumen, la clase de un objeto define:


que sabe hacer el objeto (su responsabilidad) y como (la imple-
mentacion de sus mensajes los metodos).
que mensajes particulares puede responder (protocolo o interfaz).

Para Ampliar

Una caracterstica que no veremos en profundidad es la idea de tiem-


po de vida de un objeto. En otras palabras, los objetos no son eternos:
en un momento se crean, en otro se destruyen. Cuando corresponde
que un objeto desaparezca? Quien decide destruir objetos? La prime-
ra pregunta es facil de responder: en la mayora de los lenguajes esto
se realiza de forma automatica. Quien lo realiza en estos caso recibe
el nombre de recolector de basura (del ingles gargabe collector ). Es-
ta entidad es un programa que se ejecuta a la par del programa que
definimos, pero que el programador no tiene en cuenta (decimos es
transparente al programador). Su funcion es liberar de la memoria de la
computadora aquellos objetos que no seran nunca mas utilizados. Exis-
ten diversas tecnicas que le permiten detectar esto, pero su explicacion
requiere muchsimos mas conocimientos que los que abarcaremos en
esta carpeta de trabajo.

6.2. Programacion orientada a objetos en Python


En este apartado veremos como aplicar los conceptos de programacion orien-
tada a objetos en el lenguaje P YTHON, ejemplificando los mismos, y agregando
algunos conceptos nuevos a medida que avanzamos.
En P YTHON existen dos nociones especficas, adicionales de dicho lenguaje,
que debemos comprender para poder escribir codigo orientado a objetos usando
el mismo.
La primera idea adicional de P YTHON es que todo metodo define un parame-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


175

tro especial, llamado self, que es (la referencia a) el objeto para el que estamos
definiendo este metodo. Es decir, todo metodo recibe por parametro al objeto que En algunos otros lenguajes la re-
posee dicho metodo. Esta capacidad de autoreferenciacion nos permite denotar cepcion de este parametro se en-
cuentra implcita y no debe expre-
caractersticas del mismo objeto dentro del metodo. Por ejemplo, si deseamos sarlo el usuario
implementar un metodo que llena el tanque del objeto auto por completo, debe-
mos poder referenciar al combustible que posee el auto actualmente para poder
as modificarla. De esta forma expresaremos, por ejemplo self.combustible =
100, lo cual indica que combustible es un atributo del objeto actual, y que el mis-
mo debe asociarse con el valor 100, indicando que el tanque posee el 100 % del
combustible.
La segunda idea especfica de P YTHON es que toda definicion de clase debe
implementar un metodo especial, llamado init . A este metodo se lo denomi-
na metodo de inicializacion de un objeto de esa clase, dado que define el estado
interno inicial que posee el objeto al crearse.
Ilustraremos lo expresado hasta el momento implementando el objeto auto:

class Auto():
def __init__(self):
self.combustible = 100

def moverse(self,km):
self.combustible = self.combustible - (km/40)
# Suponemos un tanque de 40 litros, y un consumo
# de 100 km por litro.

def llenarTanque(self):
self.combustible = 100

Podemos observar que el metodo init tambien recibe por parametro a self.
En este caso lo utilizamos para definir para el mismo objeto que atributos po-
seera y que valor inicial tendran. Es decir, la primera asignacion de un valor a un
atributo se considera su declaracion, como ocurre con variables dentro de un pro-
cedimiento en G OBSTONES. La diferencia entre la declaracion del atributo de un
objeto y una variable de un procedimiento radica en que el atributo puede ser re-
ferenciado desde cualquier metodo del objeto, mientras que las variables que de-
fina un procedimiento solo pueden ser utilizadas dentro de este ultimo. Ademas,
los objetos de clase Auto poseen dos metodos: moverse y llenarTanque.
Actividad de Programacion 1

Para entender mejor el funcionamiento y utilizacion de la definicion de


un objeto ejecute el siguiente programa P YTHON, ubicando primero la
definicion de la clase Auto dada anteriormente.

El siguiente programa utiliza la definicion anterior del objeto auto:

if __name__ == __main__:
# Creacion de un objeto de clase Auto
unAuto = Auto()

# Primera verificacion
print "El combustible del auto es ", unAuto.combustible

# Algunos movimientos, y su verificacion


unAuto.moverse(100) # Se mueve 100 km.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


176

unAuto.moverse(40) # Se mueve 40 km.


unAuto.moverse(30) # Se mueve 30 km.
print "El combustible luego de moverse es ", unAuto.combustible

# Cargar combustible y volver a verificar


unAuto.llenarTanque()
print "El combustible fue restaurado a " , unAuto.combustible
Procederemos a explicar detalladamente el programa anterior. Primero debemos
observar que cuando escribimos Auto() estamos creando un nuevo objeto de
clase Auto. Esto se conoce en el paradigma como la instanciacion de un ob-
jeto. Este es el momento en donde se le asigna al objeto creado su identidad
unica, con respecto a otro objeto que podamos haber creado antes, o que cree-
mos mas adelante con la misma clase. Ya instanciado, realizamos una serie de
pruebas. Primero procedemos a verificar el estado del combustible, luego envia-
mos el mensaje moverse tres veces con tres distancias diferentes, volvemos a
comprobar el combustible, y finalmente enviamos el mensaje llenarTanque.
As, en el paradigma de objetos un programa consiste en el envo de men-
sajes entre objetos, es decir, los objetos pasan a ser el centro de atencion como
En lenguajes procedurales, como elementos que forman el comportamiento del programa.
G OBSTONES, el centro de atencion
son los procedimientos y funciones. Ejemplo

El siguiente ejemplo que veremos es el de un objeto que recibe un


parametro al crearse. Implementaremos una clase que defina la estruc-
tura de una persona. De las personas se sabra solo su nombre y su
edad. Ademas un objeto persona puede recibir los mensajes crecer,
que representa el crecimiento en el da del cumpleanos, por lo que incre-
menta su edad en uno y esJoven que devuelve verdadero si la persona
posee menos de veinte anos.

Un nombre mas adecuado para el mensaje crecer podra haber sido cumplirA~
nos,
pero en P YTHON no se puede utilizar la ~
n como letra de un identificador.

class Persona():
def __init__(self, nombre):
self.nombre = nombre
self.edad = 0

def crecer(self):
self.edad = self.edad + 1

def esJoven(self):
return self.edad < 20

if __name__ == "__main__":
# Instanciamos un objeto de clase persona
unaPersona = Persona("Juan Carlos")
print "Hola! Me llamo", unaPersona.nombre

# Hacemos que la persona crezca un poco...


unaPersona.crecer()
unaPersona.crecer()
unaPersona.crecer()
unaPersona.crecer()

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


177

unaPersona.crecer()
unaPersona.crecer()

# Y verificamos como funciono


print "Tengo", unaPersona.edad, "!"
unaPersona.crecer()
print "Soy joven?", unaPersona.esJoven()

En este caso hemos pasado como argumento al momento de instanciar al ob-


jeto, el nombre de la persona, y con ello se definira el estado inicial del objeto
persona al instanciarse. Como puede observarse dicho argumento es recibido
por el metodo init . Tambien es posible ver que el metodo crecer actualiza el
estado interno del objeto para que su atributo edad se incremente en una unidad;
como este metodo es un procedimiento, no retornamos ningun valor. En cambio
el metodo esJoven corresponde con una funcion, por lo que retorna un booleano
resultante de comparar el atributo edad con el numero veinte.
Hasta ahora hemos implementado solo objetos aislados que realizan todo
su trabajo sin depender de otros objetos; pero la idea de este paradigma es
hacer que los objetos colaboren entre s para resolver diversos problemas. Este
mecanismo de colaboracion o division de problemas en distintos objetos que Esta idea es muy similar a la de
cooperan entre s es denominado como delegacion. subtareas utilizadas por procedi-
mientos.
Definicion 6.2.1. La delegacion es la colaboracion entre objetos para llevar a
cabo una tarea. Es similar a la idea de subtarea en la programacion procedural,
dado que existe un objeto que delega parte del trabajo a otro objeto.

Imaginemos entonces que tenemos dos clases de objetos, clientes y cajas de


ahorro. De una caja de ahorro nos interesa saber que saldo posee, pero nues- Modelamos a los clientes como un
tro objetivo principal sera saber si un cliente posee o no dinero en general. Los objetos que asocia a una persona
con otros atributos, como un monto
clientes pueden tener dinero en efectivo o dinero depositado en una cuenta. En- de efectivo o una caja de ahorro.
tonces para que un (objeto) cliente pueda responder si tiene dinero o no, debe
poseer una (referencia a su) caja de ahorro, para poder obtener por s misma
dicha informacion. En terminos de objetos podemos codificar algo como:

class CajaDeAhorro():
def __init__(self):
self.saldo = 0

def depositar(self, dineroADepositar):


self.saldo = self.saldo + dineroADepositar

def extraer(self, dineroAExtraer):


self.saldo = self.saldo - dineroAExtraer

class Cliente():
def __init__(self, unaPersona, unaCajaDeAhorro):
self.persona = unaPersona
self.efectivo = 0
self.cajaDeAhorro = unaCajaDeAhorro

def tieneDinero(self):
return self.efectivo > 0 or self.cajaDeAhorro.saldo > 0

def incrementarEfectivo(self, efectivoAdicional):


self.efectivo = self.efectivo + efectivoAdicional

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


178

if __name__ == "__main__":
# Instanciamos los objetos
unaPersona = Persona("Juan Carlos")
unaCajaDeAhorro = CajaDeAhorro()
unCliente = Cliente(unaPersona, unaCajaDeAhorro)

# Realizamos algunas operaciones


unaCajaDeAhorro.depositar(100)
print "Soy un cliente con dinero?", unCliente.tieneDinero()

unaCajaDeAhorro.extraer(100)
print "Tengo dinero si extraje?", unCliente.tieneDinero()

unCliente.incrementarEfectivo(100)
print "Recibi efectivo; tengo dinero?", unCliente.tieneDinero()
Nuevamente hay particularidades que nos interesa observar. Un objeto de clase
Cliente recibe en su instanciacion un objeto de clase Persona y un objeto de
clase CajaDeAhorro. Esto es as porque los objetos son como cualquier otro va-
lor que hayamos manejado hasta el momento, solo que tienen la particularidad
de poder recibir mensajes, llevando parte del programa junto con ellos. Otra co-
sa a notar es que un cliente es la asociacion entre una persona (con nombre y
edad) y los restantes atributos. Esto se relaciona con lo que en otras unidades
llamamos cuestiones de representacion de informacion. Si para el programa ne-
cesitamos que el cliente posea solamente una referencia a su caja de ahorro y no
necesitamos distinguirla de ninguna manera ni obtener ninguna otra informacion,
entonces es adecuado que otras caractersticas adicionales que se nos puedan
ocurrir para que personas de la vida real no formen parte de la representacion de
una persona en forma de objeto para este sistema.
Actividad de Programacion 2

Con base en estos ejemplos introductorios codifique los siguientes ejer-


cicios de modelado de objetos. En cada caso, construya un procedimien-
to principal para probar su codigo.

Ejercicio 6.2.1. Modelar los objetos propietario y auto, de tal manera que de un
auto se conoce su patente (que puede ser representada con un numero). Del pro-
pietario nos interesa que pueda responder al mensaje tieneUnAutoConLaPatente
que dado un numero de patante dice si un propietario posee o no un auto con
esa patente.
Ejercicio 6.2.2. Modelar un banco con clientes. El banco comienza sin clien-
tes y a traves del mensaje ingresarCliente anade uno a su lista. Tambien nos
interesa saber cuantos clientes posee y si determinado numero de documento
pertenece a alguno de sus clientes.
Ayuda: considerar la utilizacion de listas, segun se estudio en la Unidad an-
terior.
Ejercicio 6.2.3. En un mundo medieval existen guerreros. De cada guerrero se
sabe su nombre de batalla y cuanta fuerza tiene (magnitud numerica). En un
duelo entre guerreros el guerrero mas fuerte segun su nivel de fuerza ganara, y
ademas como resultado del duelo, ambos guerreros incrementan su fuerza en 1
unidad.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


179

Modelar los objetos duelo y guerrero segun se describio, haciendo que un


objeto duelo pueda recibir el mensaje entablarBatalla, que retorna el guerrero
ganador (y produce los efectos de la batalla en los participantes).

Ejercicio 6.2.4. Modele la clase Punto. Un punto conoce su coordenada x y su


coordenada y. A un punto se le puede preguntar cada una de sus coordena-
das, y tambien pueden asignarse las mismas. Ademas, todo punto debe poder
sumarse con otro punto, sumandose por un lado las coordenadas x, y por otro
lado las coordenadas y de cada punto. Como resultado debe crearse un nuevo
objeto punto que contenga el resultado de dicha operacion.

Ejercicio 6.2.5. Implementar la clase Porcentaje, de forma tal que al evaluar


este codigo

Porcentaje(15).aplicarA(2000)

se obtenga 300, que es el 15 por ciento de 2000.

6.3. Mas elementos del paradigma


Al programar utilizando el paradigma de orientacion a objetos aparecen muchas
veces problemas comunes que se repiten una y otra vez. Para resolver estos
problemas y simplificar la tarea de programacion, se definen ciertos conceptos
que permiten guiar la forma en que se programa en el paradigma. Dos de estos
conceptos, que es extremadamente importante conocer, son el polimorfismo y la
herencia. Existen otros, menos comunes, pero en esta carpeta nos concentrare-
mos solo en estos dos.

6.3.1. Polimorfismo
Una situacion recurrente al utilizar objetos es la de enviar el mismo mensaje a
muchos objetos diferentes. Pero puesto que estos objetos pueden ser instancia
de clases diferentes, entonces es necesario que todos ellos puedan entender
el mismo mensaje, aunque sea de diferentes maneras. A la caracterstica que
permite que objetos de clases diferentes respondan a un mismo mensaje se la
conoce en el paradigma orientado a objetos con el nombre de polimorfismo.

Definicion 6.3.1. El polimorfismo es una caracterstica que permite que varios


objetos respondan al mismo mensaje, aun siendo de clases diferentes.

Decimos entonces que esos objetos son polimorficos respecto de dicho mensaje.
Para ilustrar que significa precisamente la definicion anterior, imaginemos que
tenemos dos clases de objetos: perros y gatos. Ambos objetos pueden realizar
acciones similares, como son correr, respirar, dormir, comer. Consideremos, en-
tonces, el siguiente codigo:

# La clase de los perros


class Perro():
def __init__(self):
self.energiaDePerro = 200

def comer(self):
self.energiaDePerro = self.energiaDePerro + 15

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


180

def correr(self):
self.energiaDePerro = self.energiaDePerro - 8

def ladrar(self):
self.energiaDePerro = self.energiaDePerro - 2

# La clase de los gatos


class Gato():
def __init__(self,):
self.energiaDeGato = 100

def comer(self):
self.energiaDeGato = self.energiaDeGato + 10

def correr(self):
self.energiaDeGato = self.energiaDeGato - 2

def maullar(self):
self.energiaDeGato = self.energiaDeGato - 1
Ambas clases, tanto Perro como Gato, poseen dos mensajes en comun: comer
y correr. Las clases se diferencian en la forma en que perros y gatos comen y
corren, y tambien en que los perros pueden ladrar y los gatos maullar.
Diremos al enviar a un objeto el mensaje comer, por ejemplo, que dicho objeto
es tratado de manera polimorfica respecto del mensaje comer. Esto quiere decir
que no importa si quien recibe el mensaje es un Perro o un Gato; solo importa
que cualquiera de ellos puede recibir este mensaje, aunque lo implementen de
manera diferente. Esto se hace evidente con el siguiente ejemplo:
def entrenarMascota(unGatoOPerro):
unGatoOPerro.comer()
unGatoOPerro.correr()
unGatoOPerro.correr()
unGatoOPerro.correr()
unGatoOPerro.correr()
unGatoOPerro.comer()

Leer con Atencion

El anterior procedimiento recibe por parametro un objeto, que evidente-


mente puede responder a los mensajes comer y correr (de otra manera
el programa dara un error mientras ejecuta). Y como podemos observar,
no importa si el objeto recibido por parametro es en definitiva alguno de
esos dos animales, porque lo que nos interesa es la secuencia de men-
sajes enviados, que para este programa representan ejercitar un animal.

Esta caracterstica, el polimorfismo, es una de las propiedades propias del pa-


radigma de objetos y permite gran poder de expresion en los programas.
Veamos un ejemplo mas complejo. Supongamos un objeto guerrero que po-
see dos formas de atacar: estocada y garrotazo. Los guerreros empiezan con
su fuerza al cien por ciento y cuando realizan un ataque se van agotando. Si el
ataque es una estocada pierden el 2 por ciento de su fuerza, y si es un garrota-
zo, un 5 por ciento. Una forma posible para resolver lo anterior, aprovechando el
polimorfismo, es la siguiente:

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


181

class Estocada():
def realizarAtaque(self, unGuerrero):
unGuerrero.fuerza = unGuerrero.fuerza - 2

class Garrotazo():
def realizarAtaque(self, unGuerrero):
unGuerrero.fuerza = unGuerrero.fuerza - 5

class Guerrero():
def __init__(self):
self.fuerza = 100
self.tipoDeAtaque = None

def cambiarDeAtaque(self, unTipoDeAtaque):


self.tipoDeAtaque = unTipoDeAtaque

def atacar(self):
self.tipoDeAtaque.realizarAtaque(self)

Primero encontramos dos clases simples, Estocada y Garrotazo. Ambas cla-


ses de objetos poseen un mensaje en comun, realizarAtaque, por lo que po-
demos decir que los objetos son polimorficos con respecto a dicho mensaje. Notar que ambos reciben la misma
La clase Guerrero por su parte es la que implementa la logica de este pro- cantidad y tipo de parametros; esto
tambien es indispensable para que
blema. Los objetos de esta clase poseen fuerza como atributo, y tambien un estemos hablando exactamente del
tipoDeAtaque, que sera una referencia a un objeto que responde precisamen- mismo mensaje para ambos obje-
te al mensaje realizarAtaque. Es interesante observar que como inicializacion tos
del atributo elegimos asignar el valor None. Este es un valor especial que indica
la referencia nula, la que no hace referencia a ningun objeto particular. Siempre Podemos pensar en el cero en los
que debemos inicializar una variable, pero no deseamos inicializarla con ningun numeros naturales, que es un valor
especial dentro de ese conjunto.
objeto en particular, None es un buen candidato a elegir. Por ultimo existen dos
mensajes, cambiarAtaque, que recibe el tipo de ataque a asignar, y atacar, que
realiza un ataque dependiendo del tipo de ataque que posea asignado el gue-
rrero. La forma de efectuar el ataque es enviando el mensaje realizarAtaque
al atributo tipoDeAtaque (que referencia al tipo de ataque a realizar) y pasan-
do self (que es el propio objeto que recibe el mensaje, el guerrero que desea
atacar) por parametro. El polimorfismo justamente se da en relacion con que no
importa que tipo de ataque haya seleccionado el usuario, la forma de atacar
sera siempre la misma, enviar el mensaje indicado al tipo de ataque que fuere en
cada ocasion.
Actividad 3

Responda de manera coloquial: que otras formas de inicializar el tipo


de ataque podemos codificar? Piense en alguna variante que no haga
uso del valor None.

Actividad 4

Responda de manera coloquial: cuales son las precondiciones del


mensaje atacar? Que sucede si se ejecuta el metodo sin que haya
asignado ningun tipo de ataque en particular? Como informacion, None
no puede recibir ningun mensaje, dado que representa justamente una
referencia a ningun objeto.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


182

Actividad de Programacion 5

Ejecute el codigo del ejemplo anterior utilizando el siguiente codigo prin-


cipal como prueba.

if __name__ == "__main__":
# Instancia al guerrero
unGuerrero = Guerrero()
print "Mi fuerza esta en un", unGuerrero.fuerza, "%!"

# El guerrero ejecuta algunos ataques


unGuerrero.cambiarDeAtaque(Estocada())
print "Ahora dare una estocada!"
unGuerrero.atacar()

print "Oh no, mi fuerza es de", unGuerrero.fuerza, "%!"

unGuerrero.cambiarDeAtaque(Garrotazo())
print "Ahora dare un garrotazo!"
unGuerrero.atacar()

print "Rayos, mi fuerza es de", unGuerrero.fuerza, "%... :("

Para fijar el concepto de polimorfismo se proponen algunos ejercicios.


Actividad de Programacion 6

Resuelva los siguientes ejercicios haciendo uso del concepto de poli-


morfismo.

Ejercicio 6.3.1. Se desea modelar una aplicacion para guardar informacion so-
bre discos de musica (CD) y pelculas (DVD). De los CDs nos interesa conocer
el ttulo y la cantidad de temas que posee, y de los DVDs nos interesa el ttulo de
la pelcula y el tiempo total que dura.
Modelar tambien un local de venta, que conoce una serie de tems (CDs y/o
DVDs) que estan a la venta en dicho local; puede utilizarse una lista que los
contenga para modelar esta caracterstica. Para un local se tiene que poder saber
la cantidad de tems que posee y la cantidad de tems largos.
Un CD se considera largo si tiene mas de 15 canciones; en cambio un DVD
se considera largo si dura mas de 140 minutos. Notar que ambos podran res-
ponder al mensaje esLargo, cada uno implementandolo en su respectiva clase
con distinto comportamiento.

Ejercicio 6.3.2. Estar vaco es una caracterstica de muchos elementos en ge-


neral. En este caso se tiene un restaurante, que sabe la cantidad de clientes
sentados en sus mesas; una agenda telefonica, que posee una lista de numeros
de telefono; y una alcanca que posee una coleccion en monedas en su interior.
Cada elemento se encuentra codificado de la siguiente manera:

class Restaurante():
def __init__(self):
self.nroDeClientes = 0

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


183

def ingresarPersona(self):
self.nroDeClientes = self.nroDeClientes + 1

class Agenda():
def __init__(self):
self.numeros = {}

def agendar(self, nombre, tel):


self.numeros.update(nombre, tel)

class Alcancia():
def __init__(self):
self.monedas = []

def meterMoneda(self, moneda):


self.monedas.append(moneda)
Implementar un mensaje polimorfico a todos estos objetos que retorne verdadero
en caso que se encuentren vacos y falso en caso contrario.

Ejercicio 6.3.3. Una maquina de una fabrica de autos posee cuatro fases, donde
cada una le agrega una pieza particular al auto. La primera fase le agrega el
motor; la segunda, el radiador; la tercera, el tanque de combustible y la ultima, la
caja de cambios. El programa, parcialmente implementado, es el siguiente:
class AutoPorArmar():
def __init__(self):
self.piezas = []

def agregarPieza(self, nuevaPieza):


self.piezas.append(nuevaPieza)
Para simplificar las piezas son simplemente cadenas de caracteres, de tal mane-
ra que por ejemplo unAutoPorArmar.agregarPieza("motor") agrega el motor al
auto. Codificar las clases restantes Fase1, Fase2, Fase3 y Fase4, donde todas
responden al mensaje colocarPieza, colocando cada una la pieza correspon-
diente a un auto que reciben por parametro.

6.3.2. Herencia
Con el concepto de polimorfismo hemos estado modelando entidades que po-
sean un mensaje en comun, aunque distinta implementacion, es decir, no se
comportaban de la misma manera pese a poseer exactamente el mismo nombre
y recibir exactamente el mismo tipo y numero de parametros. Pero la pregunta
es, que sucede cuando tenemos un conjunto de entidades que son diferentes
pero que poseen en comun un mismo mensaje con identico comportamiento?. El
polimorfismo, por lo expresado anteriormente, no es una solucion a este proble-
ma.
Ilustraremos este concepto con un ejemplo, retomando el ejemplo de perros
y gatos. Ambos comen y corren, pero los primeros ladran y los ultimos maullan.
Supongamos que deseamos agregar ademas la posibilidad de representar tanto
animales vivos como animales muertos. O sea, queremos que tanto perros como
gatos puedan tener en su estado el atributo estaVivo. La propiedad de estar vivo
es identica a ambos seres vivos. Es un estado que es verdadero o falso. Veamos
esto en codigo:

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


184

class Perro():
def __init__(self):
self.energiaDePerro = 200
self.estaVivo = True

def seMurio(self):
return not self.estaVivo

def morir(self):
self.estaVivo = False

def comer(self):
self.energiaDePerro = self.energiaDePerro + 15

def correr(self):
self.energiaDePerro = self.energiaDePerro - 8

class Gato():
def __init__(self,):
self.energiaDeGato = 100
self.estaVivo = True

def seMurio(self):
return not self.estaVivo

def morir(self):
self.estaVivo = False

def comer(self):
self.energiaDeGato = self.energiaDeGato + 10

def correr(self):
self.energiaDeGato = self.energiaDeGato - 2

Tanto el atributo estaVivo como los mensajes seMurio y morir se codifican exac-
tamente de la misma manera (hay repeticion de codigo). La diferencia entre pe-
rros y gatos esta en que responden de diferente manera a los mensajes comer y
correr, y porque poseen un mensaje mas cada uno, que no comparten (ladrar
para Perro y maullar para Gato).
Como podemos evitar repetir el codigo identico en diferentes clases? Es
claro que la propiedad de estar vivo es algo comun, no solo a perros y gatos,
sino a todos los seres vivos. Entonces, queremos poder modelar esta idea, y
simplemente decir que tanto perros como gatos son seres vivos.
La forma de resolver esto en P YTHON, y en general en cualquier lenguaje
de programacion con objetos que nos permita programar con clases, es utilizar
Existen lenguajes que no poseen el herencia entre clases. Esta caracterstica del paradigma permite modelar una
concepto de clase, aunque no son clase que contiene exactamente las propiedades y mensajes que comparten cla-
la mayora
ses mas especializadas. En otras palabras, perros y gatos si bien son clases
distintas, podramos pensar que son de la clase SerVivo, porque poseer esa
caracterstica de poseer o no vida. En P YTHON podemos codificar lo siguiente:

class SerVivo():
def __init__(self):
self.estaVivo = True

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


185

def seMurio(self):
return not self.estaVivo

def morir(self):
self.estaVivo = False

Esta clase modela exactamente lo que tanto gatos como perros comparten. Aho-
ra lo que resta hacer es indicar que las clases Perro y Gato heredan las carac-
tersticas que provean los objetos de la clase SerVivo. O sea, debemos indicar
que tanto perros como gatos poseen todas las caractersticas y mensajes de
los seres vivos, y que ademas van a agregar algunas caractertsticas propias.
En P YTHON podemos hacer:
En realidad esta no es la forma que
class Perro(SerVivo): actualmente se utiliza en el lengua-
def __init__(self): je, pero la elegimos para esta car-
peta por su simplicidad
SerVivo.__init__(self)
self.energiaDePerro = 200

def comer(self):
self.energiaDePerro = self.energiaDePerro + 15

def correr(self):
self.energiaDePerro = self.energiaDePerro - 8

class Gato(SerVivo):
def __init__(self):
SerVivo.__init__(self)
self.energiaDeGato = 100

def comer(self):
self.energiaDeGato = self.energiaDeGato + 10

def correr(self):
self.energiaDeGato = self.energiaDeGato - 2

Observar las modificaciones que debemos realizar para que las clases Perro y
Gato, dadas previamente, para que hereden de SerVivo. La primera es indicar
en la primera lnea que declara a cada una de las clases que la clase que se
declara debe poseer las caractersticas y comportamiento de alguna ya definida,
ubicando el nombre de la clase de la cual queremos heredar entre los parente-
sis siguientes al nombre de la clase particular. La segunda es que al ejecutar la
inicializacion, debemos agregar un llamado de inicializacion a la clase de la cual
heredamos, en este caso pasando self como parametro (este es el unico caso
donde self no es implcito como parametro). Esta segunda modificacion es im-
portante dado que la clase de la cual heredamos puede poseer comportamiento
inicial que debe ser ejecutado, y self debe ser pasado como parametro porque
es a las clases particulares a las que debe hacer referencia dicha inicializacion.

Definicion 6.3.2. La nocion de herencia se utiliza en lenguajes basados en cla-


ses para indicar que una clase posee todas las caractersticas y mensajes de
otra, y ademas agrega algunas propias.

La relacion que comparten las clases que utilizan un mecanismo de herencia


para compartir comportamiento y estructura, se denomina relacion de herencia.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


186

Esta relacion indica que una clase es subclase de una superclase, siendo la
subclase quien hereda de la clase que es superclase. En nuestro ejemplo, Perro
es subclase de SerVivo, y SerVivo es superclase de Perro.
Actividad de Programacion 7

Pruebe el siguiente codigo utilizando las ultimas definiciones de


SerVivo, Perro y Gato para ver su funcionamiento.

if __name__ == "__main__":
# Instanciamos algunos seres vivos particulares
unPerro = Perro()
unGato = Gato()

# Y realizamos algunas pruebas con ellos


print "Esta vivo el perro? ", unPerro.estaVivo
print "Se murio el gato? ", unGato.seMurio()

unPerro.morir()
print "Ahora esta vivo el perro?", unPerro.estaVivo

unGato.morir()
print "Ahroa se murio el gato?", unGato.seMurio()

Puede observarse que los mensajes seMurio y morir pueden enviarse tanto a
perros como a gatos, y su comportamiento sera exactamente el mismo en ambos.
Ademas, ambas subclases ahora poseen como atributo estaVivo, aunque no lo
declaran explcitamente, sino a traves de la herencia de la clase SerVivo.
Actividad de Programacion 8

Resuelva los siguientes ejercicios haciendo uso del concepto de heren-


cia.

Ejercicio 6.3.4. Se desea modelar un sistema para una universidad que posee
estudiantes y profesores. De toda persona se sabe su nombre y edad. Pero par-
ticularmente de los estudiantes se conoce el promedio y de los profesores, la
materia que dictan. Modelar esta herencia de atributos a traves de las clases
correspondientes.

Ejercicio 6.3.5. Se desea modelar figuras de distintas clases: crculos, cuadra-


dos y triangulos. De toda figura se conoce su area y debe responder al mensaje
cabeEn que dado un tamano de area lo compara con el de la figura y responde
verdadero si el area dada por parametro es mas grande que la de la figura. Por su
parte de los crculos se sabe su radio, de los cuadrados el tamano de sus lados
y de los triangulos la cantidad de grados de cada uno de sus angulos. Los cua-
drados deben responder al mensaje agrandar que dado un tamano de lado se
agrandan exactamente dicha cantidad. Los triangulos por ultimo deben responde
al mensaje esRectangulo, que retorna verdadero si uno de sus angulos posee
exactamente noventa grados.

Las relaciones de subclasificacion pueden darse varias veces, dando lugar a una
jerarqua de clases, donde existen clases que no heredan de ninguna otra, pero

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


187

donde todas pueden tener subclases, incluso aunque ellas mismas sean subcla-
ses de otras. En este ultimo ejercicio veremos un ejemplo de jerarqua de clases
simple pero no trivial, donde habra una unica clase que no hereda de nadie, y
otras que, heredando de esta, a su vez, poseen subclases.

Ejercicio 6.3.6. Se desea modelar diferentes tipos de archivos. De todo archi-


vo se conoce su tamano, medido en Kilobytes. Existen clases de archivos como
Texto, Video, Audio y Ejecutable. De los archivos de texto se sabe su extension
en cantidad de caracteres. De los de audio y video, su extension en segundos, y
deben responder al mensaje esMasLargoQue, que dada una cantidad de segun-
dos, seg responde verdadero si la duracion es mas grande que seg. Ademas,
de los archivos de video se conoce si posee subttulos o no, y de los de audio
se conoce si poseen un idioma especfico y de ser as, cual. De los archivos
ejecutables se debe conocer la cantidad de memoria RAM que potencialmente
consumen y si necesitan permisos de administrador para poder trabajar.
Notar que los archivos de audio y video comparten un atributo y un mensaje
en comun. Pensar en modelar entonces una clase denominada Multimedia que
reuna estas caractersticas.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


188

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


189

Bases de datos
por Carlos A. Lombardi

Las bases de datos son un tema fundamental a la hora de considerar aplicacio-


nes informaticas de mas de cierta envergadura. Fueron concebidas como una
excelente solucion para el problema de persistir informacion en el tiempo, incluso
en diferentes ejecuciones de los programas utilizados. En esta Unidad presenta-
mos la idea de persistencia de la informacion, y nociones de bases de datos, que
son la herramienta conceptual mas utilizada para persistir informacion.

7.1. Persistencia de informacion


Al considerar las aplicaciones que usamos a diario al interactuar con una compu-
tadora, podemos observar la necesidad de que haya alguna forma de recordar
la informacion. Entonces, primero presentamos la idea de persistencia de infor-
macion, y analizamos las caractersticas deseables que queremos que tenga,
y justificamos su necesidad. Presentamos ademas la forma mas elemental de
persistir informacion: los archivos, y motivamos la necesidad de formas mas po-
derosas.

7.1.1. La necesidad de persistir


Hay muchos tipos de programas y aplicaciones con las que personas, grupos y
organizaciones interactuamos constantemente: el sistema de correo electronico,
el procesador de texto que usamos, el campus virtual, el sistema que usa la
Universidad para registrar la informacion de los alumnos, un juego de estrategias,
el sistema que usa el supermercado al que vamos para llevar el stock de cada
producto, el sitio en el que consultamos el pronostico del tiempo . . . es una lista
largusima.
Leer con Atencion

A estos programas se los conoce como aplicaciones informaticas. Por


que informaticas? Porque manejan informacion.

A cada uno de estos programas le va llegando la informacion que debe manejar


y mostrar a quienes lo usan. Esto pasa con todos los programas:

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


190

al sistema de correo electronico le llegan los mensajes todo el tiempo;

al procesador de texto le escribimos los textos que tiene que manejar;

la administracion de la Universidad carga las aulas en el campus virtual, y


despues los profesores ingresan los apuntes;

el personal de la direccion de Alumnos carga las notas en el sistema de


legajos;

en el juego de estrategia, los jugadores cargan, cada uno desde su browser,


los movimientos de piezas;

cada ticket que se hace en cada caja le llega al sistema de stock del super ;

al sitio del pronostico del tiempo le llegan los datos de los satelites.

Ejemplo

Si pensamos en nuestra experiencia usando programas y aplicaciones,


nos damos cuenta que casi siempre usamos informacion que a la apli-
cacion, o programa, le llego antes.
Tomemos como ejemplo el sistema de correo electronico. Cuando en-
tro, veo los mails que al correo le llegaron antes de que yo entre: esta
manana, ayer, el mes pasado. Tambien puedo ver los mails que envie yo.
O sea, puedo ver informacion que ingrese yo, y tambien informacion
que fue ingresada por otras personas. En ambos casos, la informacion
entro al sistema mucho antes de que yo entre a verla.

Con todas las otras aplicaciones que mencionamos, tambien vemos informacion
que fue incorporada anteriormente. En el procesador de texto puedo abrir un
documento que guarde la semana pasada; en el campus virtual veo los apuntes
que el profesor cargo antes; en el sistema de legajos de alumnos se tienen que
poder consultar todas las materias que aprobe; el pronostico para La Plata para
los proximos 10 das entro al sitio de pronostico del tiempo hace dos horas.

7.1.2. Persistencia de datos, mecanismos de persistencia


Para poder utilizar informacion que fue ingresada anteriormente, practicamente
todos los programas y aplicaciones tienen que tener la capacidad de almacenar,
de alguna forma, los datos que le van llegando. Se conoce como persistencia de
datos al almacenamiento de informacion en el momento en que es conocida por
un programa o aplicacion, de forma tal que la informacion pueda ser accedida en
un momento posterior.
Distintos programas y aplicaciones van a usar mecanismos de persistencia
de distntas caractersticas; hay una gran variedad en los mecanismos de per-
sistencia que una aplicacion puede usar. Las bases de datos, que son el tema
de esta Unidad, configuran un tipo de mecanismo de persistencia muy usado en
distintas clases de aplicaciones informaticas. Usaremos datos persistentes co-
mo sinonimo de datos almacenados, para reforzar que el almacenamiento se
realiza mediante un mecanismo de persistencia.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


191

Leer con Atencion

Resumiendo en una frase lo que dijimos hasta ahora, practicamente


cualquier programa o aplicacion necesita almacenar datos cuando le
llegan, para poder facilitarselos a los usuarios despues. Para esto se
utilizan distintos mecanismos de persistencia.

Antes de seguir, veamos que esto es cierto incluso para una aplicacion que aso-
ciamos con lo inmediato, como el chat. La mayor parte de la informacion que se
ingresa en una aplicacion de chat son los mensajes que escribimos, y la intencion
es que sean ledos en el momento en que los escribimos. Hasta ah la persisten-
cia de datos no tiene ningun rol. Pero al poco tiempo de usar una aplicacion de
chat, descubrimos que queremos que la aplicacion se acuerde de nuestros con-
tactos, para no tener que cargarlos cada vez que queremos hablar con ellos. La
informacion sobre contactos s debe almacenarse para uso posterior, por lo tanto
s aplica la idea de persistencia de datos. Mas adelante, descubrimos la con-
veniencia de guardar al menos algunas conversaciones que tuve por chat, para
rescatar esa direccion que me dieron y que no encuentro por ningun lado. La per-
sistencia de datos juega entonces un papel relevante, incluso en una aplicacion
inmediata como un chat.

7.1.3. Actualizacion, consulta, busqueda


Volvamos al sistema de correo electronico, enfocandonos ahora en que hace con
la informacion que maneja.El sistema debe ser capaz de actualizar la masa de
datos que administra. Hay muchas situaciones en las que hay que agregar, mo-
dificar y/o eliminar datos. Cuando llega un mail, se debe agregar a los mails
administrados por el sistema. Cuando agrego un contacto, sus datos tambien
deben ser agregados. Dentro de los datos que maneja el sistema de mail tam-
bien se incluye informacion de configuracion. Cuando yo cambio el mensaje que
quiero que enve si estoy de vacaciones, o la cantidad de mensajes que quiero
que muestre en una pantalla o pagina, estoy modificando mis datos de configura-
cion. Cuando cambio el nombre de un contacto (por ejemplo, aclaro que Roque
Perez es en rigor Roque Eduardo Perez) tambien estoy modificando informacion.
Finalmente, se le debe dar a los usuarios la posibilidad de eliminar los mails y
contactos que ya no le interesan.
Por otro lado, en muchas situaciones el sistema de correo electronico va a
hacer consultas. Para poder resolver una consulta hay que seleccionar los datos
que se pidieron de entre todos los datos almacenados a los que puede acceder el
sistema. En el sistema de correo, tengo muchas formas de elegir que mensajes
quiero ver: los mensajes que me llegaron desde una casilla, o que tengan una
palabra determinada en el texto, o que me hayan llegado entre el 1ro y el 15 de
julio, o los que envie yo, etcetera. Para cada forma de elegir que mensajes quiero
ver se debe hacer una consulta en la que se seleccionan, de entre todos los
datos de mensajes, contactos y configuracion que estan almacenados, los datos
que corresponden a los mensajes que ped ver. La informacion asociada a cada
mensaje elegido quien lo envio, para quien es, fecha, asunto, texto, etc., le llega
a la aplicacion para que la pueda mostrar por pantalla.

7.1.4. Persistencia en archivos


Hay un mecanismo de persistencia de datos que usamos todo el tiempo cuando
trabajamos con varios programas: un procesador de textos (el que tengo instala-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


192

do en mi computadora, no el que uso online), un juego de estrategia (en el que


puedo guardar el estado del juego para seguir manana), un programa de edicion
de graficos, una planilla de calculo (tambien la que esta en mi maquina).
Estos programas usan archivos: los documentos del procesador o planilla, un
archivo con la informacion de como esta el juego, un archivo grafico (.jpg, .bmp,
.png, etc.). Tpicamente, los archivos se almacenan en la misma computadora
Al menos para uso en el hogar. En en donde esta el programa.
empresas u organizaciones puede Estos archivos son el mecanismo de persistencia usado por los programas
haber servidores de archivos espe-
cializados, en los que los usuarios
indicados, y por muchos otros. En este mecanismo, es el programa el que orga-
pueden (o incluso deben) almace- niza los datos dentro de cada archivo. Por ejemplo, como indicar que una parte
nar los archivos que generan. del texto va subrayada en el procesador, que parte del archivo corresponde con
cada celda en una planilla de calculos, como se representa una zona de un grafi-
co que va en un determinado tono de verde en el editor de graficos. En general,
la forma de organizar los datos va a depender del tipo de informacion que maneja
cada programa: un texto es muy distinto a un grafico, y a su vez cualquiera de
ellos es muy distinto a una partitura que maneja un programa que permite editar
partituras musicales.
Los archivos son un mecanismo de persistencia que funciona bien para las
aplicaciones que mencionamos en este apartado. Para otros tipos de aplicacio-
nes, la persistencia de datos en archivos generados por la misma aplicacion pue-
de traer desventajas, por las caractersticas que tienen los datos que deben ma-
nejar. Para poder hablar de estas desventajas, y de un mecanismo de persisten-
cia que puede funcionar en aplicaciones en las que la persistencia en archivos
no es conveniente, vamos a presentar en forma esquematica un ejemplo de apli-
cacion para manejo de informacion, que vamos a usar varias veces durante esta
Unidad.
Ejemplo

Supongamos que queremos organizar y tener a mano la informacion


sobre los libros que lee, y que tiene en su casa, cada una de las personas
de un grupo de amigos del que formamos parte, que se esta organizando
como grupo de lectura.
Vamos a querer guardar informacion de cada libro, claro. De cada libro
nos podran interesar los autores, el idioma, el ano de la primera edicion,
la cantidad de paginas, el tipo de obra y/o genero (novela, cuentos, di-
vulgacion cientfica, historia, etc.). Tambien quienes, entre los del grupo,
tienen el libro, quienes lo leyeron, y algun comentario que tenga ganas
de hacer sobre el libro cada uno que lo leyo.
Tambien podemos querer incluir informacion sobre los escritores, o sea,
los autores de los libros: nacionalidad, fechas de nacimiento y muerte,
otros escritores con los que se haya conocido, que libros escribieron
(aunque no los tengamos ni los hayamos ledo).
Finalmente, podemos querer mantener algunos datos sobre nosotros, o
sea los integrantes del grupo de lectores: direccion, correo electronico,
edad, que tipos de libros le gustan, etcetera.

7.2. Concepto de base de datos


Como vimos hasta el momento, una posibilidad para almacenar la informacion
consiste en usar archivos. Sin embargo, los archivos presentan varios problemas
a la hora de utilizar la informacion almacenada. En este apartado vamos a exa-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


193

Ttulo Las aventuras de Carozo


Autor Ana Menseguez
Ano 2004
Idioma Espanol
Lo tienen Miguel
Romina

G.7.1. Ejemplo de ficha de un libro dentro de un documento

G.7.2. Ejemplo de planilla con informacion de libros

minar esos problemas y a presentar una solucion a los mismos: las bases de
datos.

7.2.1. Cualidades de los datos persistidos


Para que la informacion que guardamos nos sea realmente util hay ciertas ca-
ractersticas, o cualidades, que son convenientes. Las describimos, teniendo en
mente una aplicacion que maneje los datos sobre libros, escritores y lectores
segun lo que se describe en el apartado ??, y documentos de texto que se editan
con un procesador de textos, o planillas de calculo, como posibles mecanismos
de persistencia.
En primer lugar, la informacion debe estar bien organizada; conviene que
los datos del mismo tipo (por ejemplo, informacion sobre cada libro) mantenga
el mismo formato u organizacion. Si vamos a usar un documento de texto como
mecanismo de persistencia, podemos definir una ficha para organizar los datos
sobre cada libro; el grafico G.7.1 muestra una posible forma de ficha de las cuales
va a haber, en el documento, una para cada libro. Si usamos una planilla de
calculo, podemos establecer que vamos a ingresar cada libro en una fila de la
planilla; se muestra un posible formato en el grafico G.7.2.
Tener la informacion organizada es util en varios aspectos. Al definir una or-
ganizacion, queda claro que informacion se va a incluir, y por lo tanto, que hay
que saber para poder agregar datos correctamente. En el ejemplo, al ver la ficha
que corresponde a un libro, queda claro cual es la informacion sobre cada libro
que hay que tener a mano para agregar un nuevo libro. Tambien se hace mas Aunque en la aplicacion para el gru-
facil hacer algunas busquedas. Esto se ve mas en la persistencia en una planilla po de lectores estas incoherencias
no traen consecuencias graves, en
de calculo: si quiero consultar los libros editados en 1995, entonces se que la otras s pueden traerlas; por ejem-
columna donde debo buscar es la quinta desde la izquierda. Finalmente, ayuda a plo, no estara nada bien que en la
lograr otras cualidades deseadas, entre ellas las que describimos a continuacion. aplicacion que maneja la informa-
En segundo lugar, debe evitarse la duplicacion de informacion. En nuestro cion del Registro Nacional de las
Personas, aparezcan dos personas
caso, no sera correcto cargar dos veces el mismo libro. La razon principal es que con el mismo DNI y distinto nom-
se corre el riesgo de que quede informacion incoherente, por ejemplo si se carga bre.
dos veces el mismo libro pero con distintos autores. Cual de las dos copias de
los datos del libro es la que tiene los autores correctamente indicados?Estas
fallas en la calidad de la informacion son casos de la llamada inconsistencia

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


194

de datos. Como ya indicamos, para evitar inconsistencias se debe evitar que


se almacene informacion repetida. Vamos a ver un ejemplo de inconsistencia
generada por la duplicacion de datos en el apartado 7.2.3.
En tercer lugar, debe haber formas sencillas de realizar busquedas en la
informacion almacenada, de acuerdo con distintos criterios. En nuestro caso, al-
gunas busquedas posibles son: quienes leyeron un determinado libro, que libros
de cierto autor tiene alguno de nosotros, que libros de un determinado autor
leyo Romina pero no Miguel, que libros con fecha de edicion entre 1990 y 2000
leyo Lucas, que libros tenemos cuyo idioma original es sueco, etcetera. Si usa-
mos como mecanismo de persistencia un documento de texto, solo la primera de
las busquedas es facil de hacer. Al estar la informacion sobre los libros separada,
para obtener datos que incluyan varios libros, hay que copiar y pegar con pacien-
cia y sin equivocarse informacion que esta desperdigada por todo el documento.
Si se usa una planilla de calculo, algunas busquedas podran ser sencillas al acti-
var la capacidad de que muestre solamente las filas que cumplen una condicion.
Pero por ejemplo si quiero consultar que libros tiene Lucas, debo buscar en las
tres columnas (que podran ser mas) correspondientes a personas que tienen
cada libro.

7.2.2. Desventajas de la persistencia en archivos


Para el tipo de informacion que debemos manejar en la aplicacion para el grupo
de lectores, elegir un archivo (ya sea documento de texto o planilla de calculo)
como mecanismo de persistencia no ayuda a que los datos persistidos tengan
las cualidades deseadas. Agreguemos algunos comentarios a lo que ya se dijo
en el apartado 7.2.1.
Respecto de la organizacion, utilizando archivos, se puede proponer un for-
mato que los datos persistidos deben respetar, pero dependemos de que las per-
sonas (o los programas) que hagan las actualizaciones (ver el apartado 7.1.3)
respeten el formato definido. Los documentos y planillas en general no incluyen
Una excepcion son las capacida- formas de asegurar que los datos que se agregan responden a un formato defi-
des de generacion de plantillas pa- nido.
ra llenado de formularios presentes
en algunos procesadores de textos.
Respecto de la duplicacion, ni documentos ni planillas tienen forma de ase-
gurar que no se incluye informacion repetida. La persona o programa que haga
cada actualizacion, debe verificar que no se generen duplicaciones.
Respecto de las consultas, la utilizacion de documentos resulta muy poco
conveniente como ya se indico. Por su parte, las planillas de calculo pueden
funcionar razonablemente bien si tanto la informacion persistida como la consulta
a realizar son sencillas. Para consultas mas complejas la situacion cambia. Por
ejemplo, utilizando una estructura de planilla como la indicada en el grafico G.7.2,
no hay una forma sencilla de obtener los libros que tienen Marisa y Lucas pero
no Miguel, o los libros que Marisa haya conseguido antes que Lucas (agregando
la fecha en que cada persona consiguio cada libro). La utilidad de las planillas
tambien disminuye mucho ante la complejidad en los datos persistidos.

7.2.3. Un problema de consistencia


Antes de empezar a trabajar con bases de datos, veamos con un ejemplo los
problemas que pueden surgir si no evitamos la duplicacion de informacion, que
describimos brevemente en el apartado 7.2.1.
En el grafico G.7.3 vemos una forma de tener en una hoja de planilla de
calculo los datos de cada libro mas los datos de su autor. A las columnas que co-
rresponden con datos del libro (ano de edicion, idioma), le agregamos el nombre

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


195

G.7.3. Datos de libros y escritores en la misma hoja

G.7.4. Inconsistencia en los datos de Ana Menseguez

del autor, y en columnas adicionales, los datos del autor (nacionalidad, ano de
nacimiento).
En esta forma de organizar los datos estamos generando una duplicacion de
los datos de cada autor. En el grafico se ve que el dato que Ana Menseguez es
Argentina esta dos veces, y lo mismo con la fecha de nacimiento. Esta duplica-
cion puede generar inconsistencias en los datos almacenados; el grafico G.7.4
muestra un ejemplo. Se agrego otro libro de Ana Menseguez a nuestra planilla,
pero se indico para la autora un pas y un ano de nacimiento distintos. Al mirar la
planilla, no podemos determinar donde y cuando nacio Ana.

Leer con Atencion

Una organizacion incorrecta de los datos almacenados puede provocar


problemas de duplicacion y de inconsistencia.

Una forma de evitar la duplicacion es separar los datos de los autores, poniendo-
los en una hoja separada. Es lo que se propone en el grafico G.7.5. Pero lo que
ganamos en consistencia, lo perdimos en practicidad. Ahora, si estoy mirando, la
hoja con la informacion de los libros, y me da curiosidad de saber en que pas
nacio la autora de Las aventuras de Carozo, tengo que cambiar a la hoja donde
estan los escritores y buscar los datos de Ana Menseguez.

Para Ampliar

Usamos las bases de datos relacionales que vamos a estudiar en el


apartado 7.3, podremos lograr una organizacion de los datos que evite
duplicaciones e inconsistencias, y que a la vez, permita hacer consultas
que reunan los datos que queremos ver juntos.

7.2.4. Que son las bases de datos?

Las bases de datos son un mecanismo de persistencia de datos concebido para


facilitar que los datos persistidos tengan las cualidades definidas en el aparta-
do 7.2.1. Para dar una primera idea de como son las bases de datos debemos
distinguir entre base de datos y sistema de gestion de bases de datos.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


196

G.7.5. Separando los datos de libros y de escritores

Leer con Atencion

Una base de datos es un conjunto de informacion que esta almacena-


da de acuerdo con una organizacion conocida e independiente de los
programas que usen la base.

Para hablar de bases de datos se usan las siglas BD, y tambien DB que son
las iniciales en ingles. La forma en la que los datos estan organizados en una
base de datos da herramientas para evitar la duplicacion de informacion. Esta
organizacion tambien esta pensada para facilitar la forma de definir consultas,
incluyendo consultas que usen informacion desparramada por distintos sectores
dentro de la base de datos.
Definicion 7.2.1. Una base de datos (BD) es un conjunto especfico de informa-
cion que esta almacenada de acuerdo a una organizacion conocida e indepen-
diente de cualquier programa que la utilice.

Leer con Atencion

Un sistema de gestion de bases de datos es un programa concebido pa-


ra administrar bases de datos. Para nombrar a estos sistemas, se usan
las siglas SGBD, y tambien DBMS que son las iniciales en ingles.

Cuando se instala un SGBD en una computadora, el programa instalado puede


manejar una o varias bases de datos, que pueden usarse desde otros progra-
mas instalados en la misma computadora, y tambien desde otras computadoras
conectadas por Internet o por otras redes. Es importante aclarar que cualquier
actualizacion o consulta que una persona, o un programa, quiera hacer sobre
una base de datos administrada por un SGBD, debe hacerse mediante el SGBD.
En otras palabras, cualquier cosa que quiera hacer con una base de datos, se la
tengo que pedir al SGBD que la administra.
Definicion 7.2.2. Un sistema de gestion de bases de datos (SGBD) es un pro-
grama concebido para administrar bases de datos.

Se puede hacer el paralelo entre persistencia en documentos de texto o planillas


de calculo como vimos en el apartado 7.2.1, y persistencia en una base de datos,
que se muestra en el grafico G.7.6. Vemos que:
una base de datos se corresponde con un archivo o planilla, y

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


197

G.7.6. Esquema de persistencia en archivos y en bases de datos

un SGBD se corresponde con el programa (procesador de texto o progra-


ma para hacer planillas) que uso para actualizar el archivo y para hacer
busquedas.

Para persistir informacion en una BD, antes de empezar con las actualizaciones y
consultas, hay un paso previo, que es definir la organizacion de la BD. Los datos
que se agreguen despues tienen que estar de acuerdo con esta organizacion, si
no, la BD los rechaza.

7.3. Bases de datos relacionales


Entre los distintos modelos que existen para definir la organizacion de bases de
datos, las bases de datos relacionales son, por lejos, el mas usado. Los SGBD
mas populares, entre ellos el MySQL que vamos a estudiar en el apartado 7.4,
manejan bases de datos relacionales.
En este apartado vamos a estudiar los conceptos principales de las bases
de datos relacionales y a proponer la organizacion de una posible base de datos
relacional para el manejo de libros planteado en el apartado 7.1.4.

7.3.1. Tablas, campos y filas


Un concepto central en la organizacion de una base de datos relacional es el de
tabla. Una tabla puede pensarse, a grandes rasgos, como una hoja de planilla de
calculo, en la que la organizacion por columnas esta definida con precision.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


198

G.7.7. Estructura y datos de una tabla

Una tabla tiene por un lado, una estructura que define la forma que van a tener
los datos, y por otro, un conjunto de datos persisitidos. Una BD incluye un conjun-
to de tablas. En el grafico G.7.7 se muestra una posible tabla en la que se incluyen
los datos de los libros que deben persistirse en nuestra base de datos de ejemplo.
Leer con Atencion

Es importante entender que la estructura de una tabla no forma parte de


los datos persistidos. La estructura organiza los datos.

La estructura consiste en un nombre para la tabla, mas la definicion de las co-


lumnas de la tabla. Se especifica cuantas columnas tiene la tabla, y para cada
columna se establece un nombre y tambien un tipo de datos. La estructura de la
tabla que se muestra en el grafico G.7.7 le da a la tabla el nombre Libro, e inclu-
ye cuatro columnas, llamadas ttulo, ano, idioma y nomAutor respectivamente.
Por lo tanto, cada fila que se incluya en los datos de la tabla Libro va a tener
exactamente cuatro datos, ni uno mas ni uno menos. Del tipo de datos de cada
columna hablaremos un poco mas adelante.
Los datos de una tabla consisten en un conjunto de filas. En la representacion
de informacion del modelo relacional, cada fila corresponde a una entidad de la
que se quieren persistir datos. En la tabla Libro, cada fila corresponde con los
datos que se quieren persistir sobre un libro.
Leer con Atencion

En el grafico G.7.7 las filas aparecen en un cierto orden. En la organiza-


cion de los datos de una tabla no hay un orden entre las filas. Al hacer
una consulta a una BD, se puede especificar el orden en que se desea
obtener los resultados.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


199

G.7.8. Un valor incorrecto

En cada fila se indica un dato que corresponde a cada una de las columnas,
este sera el valor de la fila para cada columna. En nuestra tabla Libro, cada
fila tendra entonces cuatro datos: un ttulo, un ano, un idioma y un autor. En el
grafico G.7.7, una de las filas corresponde a los datos persistidos para el libro
Las aventuras de Carozo, los valores de esta fila para las columnas ttulo, ano,
idioma y nomAutor son: Las aventuras de Carozo, 2004, Espanol y Ana
Menseguez respectivamente.
Los nombres de las columnas son muy utiles para acceder a la informacion
almacenada en una tabla especfica. Sirven fundamentalmente para especificar
las actualizaciones y consultas que queramos hacer sobre una tabla.

Para agregar una nueva fila a la tabla Libro, debemos indicar los valores
para cada columna.

Una consulta posible sobre los datos de esta tabla puede ser obtener las
filas de la tabla Libro cuyo valor para la columna nomAutor sea Ana Men-
seguez. De esta forma obtenemos los libros de esta autora cuyos datos
estan persistidos en nuestra BD.

7.3.2. Tipos de datos


Algunas columnas podran admitir solamente ciertos valores. Por ejemplo, en la
tabla Libro, no sera correcto incluir una fila cuyo valor para la columna ano sea
Quiroga; ver grafico G.7.8.
El tipo de datos que se especifica para cada columna evita que puedan agre-
garse filas a una tabla cuyos valores no se correspondan con el sentido de cada
columna.
Aunque los tipos de datos disponibles y sus nombres varan de SGBD a
SGBD, todos ellos permiten especificar, entre otros, estos tipos de datos:

Texto libre, con un maximo de caracteres de longitud.

Numeros, con o sin decimales.

Fechas.

En nuestra tabla Libro, los tipos de dato para las columnas ttulo, idioma y
nomAutor podran ser texto libre hasta 120 caracteres, mientras que para ano
resulta mas adecuado un tipo numerico sin decimales.
Veremos como especificar el tipo de dato de cada columna al describir la
creacion de una tabla con MySQL.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


200

G.7.9. Valor repetido en clave primaria

7.3.3. Claves
Un elemento adicional en la definicion de la estructura de una tabla es su clave
primaria, que es una columna incluida en la definicion de la tabla. Las claves pri-
La clave primaria de una tabla pue- marias son conocidas comunmente como PK, por las iniciales del ingles primary
de constar de varias columnas; no key.
estudiaremos esta posibilidad en la
rapida introduccion a las bases de
datos relacionales que estamos ha-
Definicion 7.3.1. Una clave primaria (del ingles primary key) es un atributo (una
ciendo. columna) de una entidad que la identifica de manera unvoca.

El SGBD considerara, para cada fila de la tabla, al valor de la columna elegida


como clave como identificador de dicha fila. Por lo tanto, no permitira que haya
dos filas con el mismo valor para la columna de la clave.
En la tabla Libro descripta en el grafico G.7.7, la opcion mas razonable es
especificar a la columna ttulo como clave primaria de la tabla. Por lo tanto, si se
quiere agregar una nueva fila a la tabla con el ttulo El cachalote contento, el
SGBD impedira esta actualizacion, porque ya hay una fila en la tabla con ese va-
lor para la columna que es clave primaria. El caso se describe en el grafico G.7.9.

7.3.4. Varias tablas


En el modelo relacional, una base de datos esta compuesta por varias tablas, y
cada una de estas pueden referenciar a entidades en otras tablas.
En el grafico G.7.10 se incluyen algunas tablas que forman parte, junto con
la tabla Libro descrita en el grafico G.7.7, de la BD con datos persistidos sobre
libros, escritores y lectores. La leyenda (c.p.) al lado de un nombre de columna
indica la clave primaria de cada tabla.
Observamos que aparecen columnas con el mismo nombre en distintas ta-
blas. Por ejemplo, nomAutor aparece en Libro y Escritor, apodoLector apa-
rece en Lector y TieneLibro. Esto esta marcando que, dentro de una tabla, los
valores de una columna pueden verse referencias a filas de otra tabla. Por ejem-
plo, los valores de la columna nomAutor en la tabla Libro pueden considerarse
referencias a las filas de la tabla Escritor, que contienen los datos persistidos
sobre cada escritor. Las referencias entre tablas seran aprovechadas para hacer
consultas que unan datos de distintas tablas.
La nocion de referencia puede incluirse en la organizacion de una BD, inclu-
yendo en una tabla claves foraneas a otras tablas. Aunque no describiremos esta
En ingles se las denomina fo- caracterstica en esta breve introduccion, la mencionamos para quienes quieran
reign key. Es usual llamarlas cla- conocer mas sobre las bases de datos relacionales.
ves foraneas, aunque una traduc-
cion mas adecuada habra sido cla-
ves extranjeras.
Definicion 7.3.2. Una clave foranea (del ingles foreign key) es un atributo de una
entidad, pero que hace referencia a una clave primaria de otra entidad en alguna
otra tabla de la BD.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


201

G.7.10. Otras tablas para la BD de libros y lectores

Observemos ahora la tabla TieneLibro. Cada fila de esta tabla representa el


hecho de que uno de los lectores tiene un determinado libro. Por ejemplo, de
acuerdo a los datos que se ven, Andrea, Romina y Joaqun tienen el libro Pig-
mallion, mientras que Miguel y Lucas no lo tienen. Destacamos que ni titulo
ni apodoLector podran servir como clave primaria de esta tabla, porque debe
permitirse que existan distintas filas con el mismo valor en titulo (representan-
do varios lectores que tienen, cada uno, un ejemplar del libro correspondiente)
y tambien que existan distintas filas con el mismo valor en apodoLector (repre-
sentando distintos libros de los cuales un mismo lector tiene ejemplares). Como
cada tabla debe tener una clave primaria, se opto por agregar una columna adi-
cional con un numero correlativo, y establecer a esta columna agregada como la
clave primaria de la tabla TieneLibro.
Cuando la clave primaria de una tabla es una columna que corresponde a un
dato propio de lo que representa cada fila (ttulo de un libro, nombre y apellido de
un escritor), se dice que la tabla tiene una clave de negocio. Por el contrario, si la
clave primaria corresponde a una columna agregada ad hoc para tener un valor
que sea distinto para cada fila, hablamos de clave tecnica.

Definicion 7.3.3. Una clave de negocio es una clave primaria que corresponde
a datos propios de las entidades que estan siendo representadas.

Definicion 7.3.4. Una clave tecnica es una clave primaria que se agrega a la
entidad para identificarla, cuando ninguno de sus atributos originales es unico.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


202

7.4. Introduccion a SQL

Como se describio en el apartado 7.2.4, para hacer cualquier operacion sobre


una base de datos relacional, deberemos comunicarnos con un SGBD. En esta
unidad usaremos el SGBD llamado MySQL, una alternativa gratuita, completa y de
utilizacion sencilla.
Para indicar a un SGBD que operaciones de actualizacion y consulta de una
Recordar que en el apartado 7.1.3 base de datos relacional realizar, se utiliza el lenguaje SQL, que fue definido a
se describe que operaciones deben tal efecto. Este lenguaje define un conjunto de comandos o instrucciones, que
poder hacerse sobre una BD.
permiten describir todas las operaciones que podemos realizar sobre una BD. Al-
gunos de los comandos mas usados son insert, update y (sobre todo) select,
que definen las operaciones de agregado, modificacion y consulta de filas. Des-
cribiremos estos comandos, y algunos otros, en el resto de este apartado.
A partir de los comandos se construyen expresiones, que son las oraciones
del lenguaje SQL. Ejecutando estas expresiones se indica al SGBD las operacio-
nes que se desea realizar.

Ejemplo

Por ejemplo, utilizando el comando select se puede construir una ex-


presion para obtener los ttulos de los libros cuya autora es Ana Men-
seguez. Ejecutando esta expresion obtendremos el resultado deseado,
que de acuerdo con el grafico G.7.7, sera la lista con los valores Las
aventuras de Carozo y Pesca Pipo pesca.

En este apartado vamos a describir algunas caractersticas basicas del len-


guaje SQL, y lo vamos a utilizar para crear una base para persistir datos sobre
libros, escritores y lectores. Veremos como definir la organizacion de la BD, como
hacer operaciones de actualizacion, y finalmente como hacer consultas.

Para Ampliar

En esta unidad solo vamos a describir una pequena proporcion de los


comandos disponibles en SQL.
Para conocer mas, se puede consultar el manual de usuario de MySQL,
que esta disponible en forma gratuita en:

http://dev.mysql.com/doc/refman/5.0/es/

7.4.1. Estructura y ejecucion de las expresiones SQL

Cada expresion SQL incluye el nombre de un comando que indica el tipo de ope-
racion que deseamos realizar (agregar filas, hacer una consulta, etc.), parame-
tros que indican sobre que objeto (base de datos, tabla, columna, etc.) debe apli-
carse esta operacion, y muchas veces informacion adicional que es necesaria
para definir la operacion.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


203

Leer con Atencion

Las expresiones SQL deben terminar con punto y coma para poder ser
comprendidas adecuadamente por el SGBD.

Ejemplo

Por ejemplo, la expresion que debemos ejecutar para agregar, en la ta-


bla libro, la fila que corresponde al libro Las aventuras de Carozo en
el grafico G.7.7, comienza con el nombre del comando correspondiente
que es insert, seguido por el nombre de la tabla en la que se desea
agregar una fila (en este caso libro), y por los valores que debe tener la
nueva fila para cada columna (en el ejemplo, Las aventuras de Carozo,
2004, Espanol y Ana Menseguez). En el apartado 7.4.3 se describe
la expresion para agregar esta fila, y tambien la forma general de las
expresiones que definen las operaciones de agregado de filas, corres-
pondientes al comando insert.

La forma mas sencilla para ejecutar un comando SQL en el MySQL Workbench es


escribirlo en el area de comandos, ubicar el cursor dentro del comando (o sea,
antes del punto-y-coma final), y pulsar Ctrl-Shift-Enter.

7.4.2. Definiendo la organizacion de una BD

El MySQL que hemos instalado tiene la capacidad de administrar varias bases de


datos. Lo primero que vamos a hacer es crear una nueva base de datos. Para
ello usamos el comando create database. Ejecutamos
create database libros;
Si el comando se ejecuta correctamente, entonces hemos agregado una nueva
BD que sera administrada por nuestro MySQL.
El siguiente comando le indica a MySQL que, entre las distintas BD que puede
administrar, vamos a trabajar con la que se llama libros. Esta es la funcion del
comando use, que usaremos de esta forma:
use libros;
La BD libros, recien creada, no contiene ninguna tabla. Para crear una nueva
tabla utilizamos el comando create table. La sintaxis de este comando es bas-
tante compleja, pues pueden incluirse varias columnas que se agregaran en la
estructura de la tabla que se cree. Estudiemosla mediante un ejemplo, que crea
la tabla libro tal como se describe en el grafico G.7.7.
create table libro (
titulo varchar(120) primary key,
anio integer(5),
idioma varchar(120),
nomAutor varchar(120)
);

La estructura general de las expresiones correspondientes al comando create


table es:

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


204

create table < nombre > (


< columna >,
< columna >,
...
< columna >
);
o sea, las palabras create table seguidas del nombre de la nueva tabla, y luego
entre parentesis, las descripciones de cada columna separadas por comas. A su
vez, cada columna se especifica como sigue
< nombreColumna > < tipoDatos > < especificacionesAdicionales >
Los tipos de datos que vamos a usar son varchar e integer, que representan
Existen en rigor muchas variantes texto libre y numeros sin decimales respectivamente. En ambos casos, el tipo de
de tipos de datos para texto libre y datos se acompana de un numero entre parentesis, que representa la longitud
para numeros, pero no vamos a uti-
lizarlas todas, pues muchas son ne-
maxima que pueden tomar los valores de la columna que se esta definiendo. En
cesarias por razones tecnicas que el ejemplo, se permiten textos libres de hasta 120 caracteres en las columnas
escapan al alcance de esta intro- titulo, idioma y nomAutor, y numeros de hasta 5 cifras en anio. Agregamos la
duccion. especificacion adicional primary key para la columna que elegimos como clave
primaria de la nueva tabla.
A continuacion, indicamos los comandos que crean las tablas descritas en el
grafico G.7.10

create table escritor (


nomAutor varchar(120) primary key,
paisNacim varchar(120),
anioNacim integer(5)
);
create table lector (
apodoLector varchar(120) primary key,
nombreYApe varchar(120),
mail varchar(250)
);
create table tieneLibro (
nro integer(5) auto increment primary key,
titulo varchar(120),
apodoLector varchar(120),
desde integer(5)
);

En la definicion de tieneLibro le agregamos la especificacion auto increment a


la columna nro. De esta forma, el mismo SGBD va a agregar un numero correla-
tivo a cada fila que agreguemos a esta tabla.
Podemos verificar que las tablas que creamos tienen la estructura deseada
mediante el comando describe < tabla >;. Probar por ejemplo con
describe libro;

Leer con Atencion

Los comandos indicados en este apartado pueden variar entre distintos


SGBD. Si se va a utilizar un SGBD distinto a MySQL, debe verificarse el
nombre y la sintaxis de cada comando a utilizar.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


205

7.4.3. Agregado de filas


El comando create table crea la estructura de una tabla, pero no le agrega
datos. Para saber cuantas filas de datos tiene una tabla podemos ejecutar el
siguiente comando
select count(*) from < tabla >;
Si se ejecuta para cualquiera de las tablas creadas se obtendra 0 como resultado.
Para agregar una fila a una tabla usamos el comando insert. Al igual que
lo hicimos con create table, brindaremos primero un ejemplo de uso de este
comando, y luego lo describiremos. En este ejemplo agregamos a la tabla libro
la fila que representa al libro Las aventuras de Carozo.
insert into libro(titulo, anio, idioma, nomAutor)
values(Las aventuras de Carozo, 2004
,Espa~ nol, Ana Menseguez);
Dentro de esta expresion podemos reconocer: el nombre de la tabla a la que
queremos agregar una fila, libro; los nombres de las columnas para las que
indicamos valores, titulo, anio, idioma y nomAutor, y finalmente los valores
que queremos que tenga la nueva fila, que son Las aventuras de Carozo,
2004, Espa~ nol y Ana Menseguez.
A partir de estas observaciones resulta sencillo comprender la estructura ge-
neral de las expresiones correspondientes al comando insert

insert into < tabla >(< col-1 >,< col-2 >,... < col-n >)
values (< val-1 >, < val-2 >, ... < val-n >);
donde las listas de nombres de columnas y valores deben tener la misma canti-
dad de elementos, y la nueva fila tendra a < val-i > como valor de cada columna
< col-i > incluida en la lista de columnas.
Para Ampliar

El comando insert tiene muchas variantes que permiten agregar varias


filas a la vez. No incluiremos estas variantes en la presente introduccion
a SQL.

Agreguemos una segunda fila en la tabla libro

insert into libro(titulo, anio, idioma, nomAutor)


values(El cachalote contento, 1987
,Espa~
nol, Eva Condal);

Actividad 1

Utilizando el comando insert agregar en la tabla libro el resto de las


filas descriptas en el grafico G.7.7, mas otras cuatro que correspondan
a libros que Ud. conozca. Verificar luego que la cantidad de filas de la
tabla libro se corresponde con lo esperado.

7.4.4. Consultas sobre una unica tabla


Como saber si los valores de las filas que agregamos a la tabla libro son los
que quisimos poner? Para averiguarlo vamos a realizar una consulta sencilla:
queremos obtener todos los datos incluidos en la tabla libro.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


206

G.7.11. Resultado de select * from libro;

G.7.12. Resultado de la segunda expresion select

El comando de SQL que corresponde a las consultas es select. En el apar-


tado anterior ya lo utilizamos para obtener la cantidad de filas de una tabla.
Para obtener todos los datos incluidos en libro, simplemente ejecutamos
select * from libro;
Si incluimos en la tabla las filas descriptas en el grafico G.7.7, obtendremos el
resultado que se muestra en el grafico G.7.11. Observamos que este resultado
tiene la misma forma de la tabla, con sus filas y columnas. Modificando la expre-
sion, podemos controlar las columnas y las filas que obtenemos como resultado
de una expresion select.
Leer con Atencion

El comando select nos permite acceder a datos incluidos en una BD.


El comando describe, que usamos en el apartado 7.4.2, permite el ac-
ceso a parte de la estructura de una BD.
La diferencia entre datos y estructura esta explicada en el aparta-
do 7.3.1.

Mediante la siguiente expresion obtendremos solamente una parte de los datos


de la tabla libro, restringiendo tanto las filas como las columnas que apareceran
en el resultado.
select titulo, anio
from libro
where nomAutor = Ana Menseguez;

En el grafico G.7.12 se muestra el resultado de esta consulta, que es un extracto


de la tabla libro. Los datos incluidos corresponden solamente a los libros escritos
por Ana Menseguez, o sea, a las filas de la tabla cuyo valor para la columna
nomAutor es Ana Menseguez. Esta restriccion de filas es el resultado de haber
agregado a la expresion la parte where nomAutor = Ana Menseguez;.
Ademas, para cada fila elegida se incluyen solamente los valores de las co-
lumnas titulo y anio. Esta restriccion de columnas es el resultado de haber co-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


207

locado select titulo, anio en lugar de select * al principio de la expresion.


A partir de este ejemplo podemos hacer una primera descripcion general de
las expresiones que podemos armar a partir del comando select, a las que tam-
bien llamaremos consultas:
select < columnas >
from < tabla >
where < condicion >;

La definicion del comando select en SQL incluye una gran cantidad de variantes
para especificar < columnas >, < tabla > y < condicion >. De esta forma, per-
mite describir una amplia variedad de consultas sobre una BD. A continuacion
describimos algunas de estas variantes.
Respecto de las columnas, en los ejemplos vistos hasta ahora se utilizaron
tres variantes: *, < col-1 >, < col-2 >, ... y count(*).

Utilizando * se obtienen todas las columnas de la tabla, como en la consulta

select * from libro;


ya comentada.

Utilizando la forma < col-1 >, < col-2 >, ... se indica explcitamente
que columnas se quiere obtener como resultado de la consulta. Es la op-
cion utilizada en la consulta
select titulo, anio
from libro
where nomAutor = Ana Menseguez;

Utilizando count(*) se obtiene un resultado que incluye una sola fila y una
sola columna, o sea, un solo valor. Este valor es la cantidad de filas de la
consulta. Notar que la cantidad de filas que aparecen en una consulta pue-
de ser distinta a la cantidad de filas que hay en la tabla correspondiente. Por
ejemplo, si los datos de la tabla libro se corresponden con el grafico G.7.11,
entonces el resultado de
select count(*) from libro;
es 5, mientras que el de
select count(*)
from libro
where nomAutor = Ana Menseguez;
es 2.

Leer con Atencion

Si se usa count(*) en una consulta, conviene que sea lo unico que se


incluye en la especificacion de columnas. Incluir en una misma consulta
count(*) junto con * o un detalle de columnas, puede producir resulta-
dos incorrectos.

Respecto de la tabla, hasta ahora hemos incluido siempre el nombre de una unica
tabla. Veremos ejemplos de consultas que involucran varias tablas mas adelante,
en el apartado 7.5.3.
Respecto de la condicion, ademas del comparador por igualdad = se pueden
usar, entre otros, la comparacion por desigualdad !=, y las comparaciones <=, >=,

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


208

< y >. Todos son validos tanto para valores numericos como para texto; en este
ultimo caso se considera el orden de diccionario, por ejemplo alfa < beto
< betun.
Puede compararse el valor de una columna contra un valor fijo, como en la
comparacion nomAutor = Ana Menseguez, o tambien los valores de dos co-
lumnas entre ellos. Por ejemplo, la consulta
select * from libro where titulo < nomAutor;
incluira al libro El cachalote contento, pues este ttulo esta antes en el diccio-
nario que Eva Condal, que es el nombre de la autora. Por su parte, el libro
Pigmallion no sera incluido, porque segun el orden del diccionario el nombre de
su autor, George Shaw, esta antes que el ttulo del libro, por lo tanto la condicion
Al juntarse nombre y apellido del titulo < nomAutor resulta falsa en este caso.
autor en una unica columna, el va- Tambien pueden incluirse varias condiciones, usando los operadores logicos
lor con que se compara es George
Shaw y no solamente Shaw, por
and, or y not, entre otros. Por ejemplo, el resultado de la consulta
eso resulta estar antes que Pigma- select *
llion. from libro
where nomAutor = Ana Menseguez and anio >= 2006;
seran los datos correspondientes a los libros escritos por Ana Menseguez de
2006 en adelante, mientras que el resultado de
select *
from libro
where nomAutor = Ana Menseguez or nomAutor = Eva Condal;
seran los datos correspondientes a los libros que hayan sido escritos por alguna
de las dos autoras mencionadas en la consulta.
Finalmente, observamos que si no se coloca ninguna condicion, como por
ejemplo en:
select titulo, anio from libro;
no se esta estableciendo ninguna restriccion sobre las filas a incluir en el resul-
tado de la consulta, que por lo tanto incluira informacion de todas las filas de la
tabla libro. En este caso, se omite la palabra where.
Como ya hemos hecho en algunos ejemplos es posible utilizar solamente la
restriccion de filas dada por la condicion, solamente la restriccion de columnas
dada por una lista explcita de columnas, o ambas a la vez en la misma consulta.
Actividad 2

Escribir consultas para obtener cada uno de los conjuntos de datos pe-
didos en el siguiente ejercicio.

Ejercicio 7.4.1. Obtener la siguiente informacion de la base de datos usada co-


mo ejemplo.

Ttulo, ano y autor de los libros escritos en el ano 1987.

Ttulo y ano de los libros escritos hasta el ano 1987 inclusive.

Todos los datos de los libros escritos entre los anos 1900 y 1999.

Todos los datos de los libros cuyo idioma no sea el espanol.

Todos los datos de los libros que o bien se han escrito en frances o bien
fueron escritos despues del ano 2000.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


209

G.7.13. Ordenando las filas del resultado de una consulta

El ano de todos los libros registrados en la tabla libro.

La cantidad de libros cuyo idioma es el espanol.

7.4.5. Ordenando el resultado de una consulta


El resultado de la mayor parte de las consultas (expresiones construidas a partir
del comando select) incluye varias filas; por ejemplo, las cinco filas del grafi-
co G.7.11 que son el resultado de la consulta select * from libro;. En este
caso, el resultado es una lista ordenada de filas: la que aparece arriba se consi-
dera la primera, la que esta debajo de esta es la segunda, y as hasta la ultima.
En todos los ejemplos del apartado 7.4.4, las filas dentro del resultado de una
consulta aparecen ordenadas en forma aleatoria. Es posible indicar, al hacer una
consulta, que las filas en el resultado aparezcan ordenadas segun el valor de
una columna. Para eso debe agregarse al final de la expresion SQL las palabras
order by, seguidas del nombre de la columna elegida.
Ejemplo

Por ejemplo, para obtener todos los datos de la tabla libro, ordenando
las filas segun el ano de cada libro, se puede ejecutar esta consulta:
select * from libro order by anio;

Tambien se puede indicar que las filas aparezcan en el orden inverso al que
corresponde a una columna, para eso se agrega la palabra desc a continuacion
del nombre de la columna. Por ejemplo en el resultado
select * from libro order by anio desc;
la primera fila sera la del libro mas reciente. En el grafico G.7.13 se muestra el
resultado correspondiente a estas consultas.
La indicacion de orden puede combinarse con las restricciones de filas y/o
columnas. Puede verse un ejemplo en el grafico G.7.14. Observar que no es
necesario que las columnas involucradas en la condicion o el orden aparezcan en

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


210

G.7.14. Una consulta con restricciones y orden

el resultado. En este ejemplo, la condicion refiere al idioma, y el orden al ano de


cada libro, mientras que ninguno de estos datos se incluye entre los resultados.
Actividad 3

Escribir una consulta para obtener todos los datos de los libros escritos
a partir de 1900, ordenados segun el nombre del autor.

Actividad 4

Escribir una consulta para obtener ttulo e idioma de los libros escritos
en espanol, en orden inverso respecto del ttulo.

7.5. SQL mas avanzado


Como mencionamos, el lenguaje SQL tiene una diversidad importante de alterna-
tivas para realizar operaciones complejas con bases de datos. En este Apartado
vamos a profundizar en algunas de ellas.

7.5.1. Calculos en las consultas


A partir de lo visto en apartados anteriores, podemos concluir que el formato ge-
neral de una consulta sera
select < columnas >
from < tabla >
where < condicion >
order by < orden >;
en donde tanto la condicion como el orden son opcionales, o sea, pueden no
incluirse. Una variante importante en este esquema es que una o varias columnas
correspondan a un calculo sobre los valores de cada fila.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


211

G.7.15. Resultado de consultar en que ano cumple un siglo cada libro

Ejemplo

Por ejemplo, si queremos mostrar en que ano cada libro va a cumplir un


siglo desde su escritura, podemos realizar la siguiente consulta
select titulo, anio, anio + 100 as unSigloDesdeAnio
from libro
where nomAutor = Ana Menseguez;
obteniendose el resultado del grafico G.7.15.

En esta consulta, la especificacion anio + 100 as unSigloDesdeAnio indica que


debe incluirse, en el resultado de la expresion select, una columna cuyo resulta-
do sea el valor de la columna anio de cada fila mas 100. Llamaremos columnas
calculadas a estas columnas que se incluyen en una consulta, y cuyo valor no
sale directamente de la BD. El nombre de una columna calculada se indica en la
misma especificacion de columna, luego de la palabra as; en el ejemplo se asigna
el nombre unSigloDesdeAnio a la columna calculada incluida en la consulta.
Leer con Atencion

Si se incluyen columnas calculadas en una consulta, se obtendra un re-


sultado que contiene columnas que no corresponden a ninguna columna
en la BD. Por lo tanto, las consultas sirven no solo para extraer da-
tos de la BD, sino que tambien pueden realizar operaciones sobre
estos datos. Estas operaciones solamente afectan al resultado de la
consulta, no implican ninguna modificacion en la BD.

Ademas de las cuatro operaciones aritmeticas basicas, los distintos SGBD ofre-
cen una gran cantidad de funciones matematicas, de tratamiento de texto, y otras
que pueden ser utilizadas para definir columnas calculadas dentro de una con-
sulta. Destacamos algunas funciones provistas por MySQL:
la parte entera de < numero >.
floor(< numero >)
Por ejemplo: floor(3.8) es 3.
el valor absoluto de < numero >.
abs(< numero >)
Por ejemplo: abs(-3.8) es 3.8.
los primeros n caracteres del texto especificado.
left(< texto >,< n >)
Por ejemplo: left(Orqudea.4) es Orqu.
right(< texto >,< n >) analogo a left pero tomando los ultimos caracte-
res, en lugar de los primeros.
char length(< texto >) la cantidad de caracteres del texto especificado.

Utilizando estas funciones podemos armar una consulta en la que obtenemos,

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


212

G.7.16. Consultas con varios calculos

para cada libro en idioma espanol, la inicial del ttulo y la ultima cifra del ano.
select titulo, anio,
left(titulo,1) as inicial,
anio - (floor(anio / 10) * 10) as ultCifraAnio
from libro
where idioma = Espa~ nol;
Aunque no es imprescindible, resulta siempre conveniente asignar un nombre
a cada columna calculada que se incluye en una consulta. En el ejemplo, los
nombres asignados a las dos columnas calculadas son inicial y ultCifraAnio.
Las operaciones y funciones tambien pueden ser utilizadas dentro de la con-
dicion al definir una consulta. En el siguiente ejemplo solo se incluyen las filas
correspondientes a libros cuyo ttulo empieza, con E o bien con P.
select titulo, anio, left(idioma,2) as idiomaResumido
from libro
where left(titulo,1) = E or left(titulo,1) = P;
En esta consulta se incluyeron calculos tanto en las columnas como en la condi-
cion. El grafico G.7.16 muestra los resultados de las dos ultimas consultas des-
critas.
Actividad 5

Realizar el ejercicio 7.5.1 y constatar que los resultados se corresponden


con la informacion solicitada.

Ejercicio 7.5.1. Obtener mediante consultas los datos solicitados.

El ttulo y el siglo de los libros cuyo ttulo tenga al menos 20 caracteres. El


siglo se obtiene sumando uno a la parte entera de (ano / 100). Por ejemplo,
el ano 1848 corresponde al siglo (1848 / 100) + 1 = 19.

El ttulo entero, la ultima letra del ttulo, el ano y el autor de los libros de los
cuales el nombre del autor empieza con A.

7.5.2. El valor nulo


Consideremos la siguiente expresion que permite agregar una nueva fila en la
tabla libro:
insert into libro(titulo, anio, nomAutor)
values(Don Quijote, 1605, Miguel de Cervantes);

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


213

G.7.17. Valor null en la columna idioma

Esta expresion tiene una diferencia respecto de las que estudiamos en el apar-
tado 7.4.3: no se especifican valores para todas las columnas. Observamos
que no se especifica el valor para la columna idioma.
En el apartado 7.3.1 vimos que cada fila de una tabla tiene un valor para
cada una de las columnas. Cual sera el valor de la nueva fila para idioma?
Podemos averiguarlo haciendo la consulta que mostramos en el grafico G.7.17.
Observamos que en idioma aparece una leyenda especial que dice NULL.
Leer con Atencion

El SGBD le asigno a esta columna un valor especial, llamado null, que


es distinto a cualquier otro valor posible. En particular null es distinto
al texto null o NULL. Esto es as porque son valores de distintos
tipos y no representan lo mismo. As, null es utilizado en reemplazo de
cualquier valor cuando queremos indicar la ausencia de ese dato.

Definicion 7.5.1. El valor null es un valor especial definido en SQL. Es distinto


a cualquier otro valor posible. Un valor null puede significar que la columna no
debe llevar valor o bien que se desconoce cual es el valor que debe ir.

Leer con Atencion

Se considera que si el valor para una columna en una fila es null, enton-
ces la fila no tiene valor asignado para esa columna. En el ejemplo,
podemos decir que la fila agregada no tiene valor asignado para idioma,
o lo que es lo mismo, que no tiene idioma asignado.

En el ejemplo se muestra que al ejecutar una expresion insert se asigna el valor


null a las columnas para las que no se haya especificado valor. Puede haber
mas de una columna en estas condiciones, por ejemplo
insert into libro(titulo, idioma) values (Odisea, Griego);
Tambien puede asignarse especficamente el valor null, por ejemplo la expresion
insert into libro(titulo, anio, idioma, nomAutor)
agrega una fila en la
values(Cantar de Mio Cid, null, null, null);
tabla libro en la que todos los valores son null salvo el ttulo. El grafico G.7.18
muestra los datos incluidos en la tabla libro luego de ejecutar las expresiones
insert que describimos.
Observamos que cualquier columna puede incluir valores null, independien-
temente del tipo de datos de la columna. En el ejemplo, hay filas con valor null
en la columna anio, que es de tipo numerico, y tambien hay filas con valor null
en las columnas idioma y/o nomAutor que son de tipo texto.
El valor null tiene un comportamiento particular respecto de las comparacio-
nes por igual o distinto, o sea = y !=, de las que hablamos en el apartado 7.5.1.
Por ejemplo, si ejecutamos

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


214

G.7.18. Varios valores null

select * from libro where idioma = null;


para obtener los datos de los libros que tienen null como valor en idioma (o sea,
que no tienen idioma asignado) encontraremos que el resultado de esta consulta
no incluye ninguna fila. Curiosamente, la consulta
select * from libro where idioma != null;
tampoco incluye filas en el resultado.
Leer con Atencion

La comparacion por igual o distinto de null contra cualquier valor da co-


mo resultado null, o sea, ni verdadero ni falso. Por eso deben utilizarse
formas de comparacion especficas para la deteccion de valores null.
El lenguaje SQL incluye la pregunta is null que es verdadera para los
valores que son iguales a null. Tambien existe is not null que es ver-
dadera cuando el valor no es igual a null. Por ejemplo, para obtener los
datos de las filas donde el idioma no es igual a null, podemos ejecutar
la consulta:
select * from libro where idioma is not null;

Actividad 6

Obtener mediante consultas siguientes datos:

El ttulo de los libros para los cuales el valor de idioma es nullo


bien el valor de nomAutor es null.
El ttulo y el ano de los libros que tengan asignado valor para ano,
pero no para idioma.
La inicial del ttulo de los libros que no tengan ni autor ni ano asig-
nados.

7.5.3. Consultas sobre varias tablas


Todas las consultas que hicimos hasta ahora extraen datos de una unica tabla;
para todos los ejemplos nos hemos referido a la tabla libro. En este apartado ve-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


215

G.7.19. Libros que consideraremos en el apartado 7.5.3

G.7.20. Reunion natural de filas en dos tablas separadas

remos como hacer algunas consultas que integran datos que estan en distintas
tablas. En los ejemplos consideraremos que las tablas escritor, lector y tiene-
Libro incluyen las filas que se muestran en el grafico G.7.10. Respecto de libro,
supondremos que tiene las filas que se muestran en el grafico G.7.19.
Supongamos que queremos saber, para el libro El cachalote contento, el
ano de edicion, idioma y autora que estan en la tabla libro, y ademas, el pas y
ano de nacimiento de su autora, que estan en la tabla escritor. Para ello vamos
a realizar una consulta que reune datos que, en la BD, estan separados en dos
tablas distintas. Esta consulta debe seleccionar una fila en cada una de las tablas.
La situacion se describe en el grafico G.7.20.
La fila de libro que incluye los datos que buscamos es la que corresponde
al libro sobre el que queremos consultar datos; puede seleccionarse facilmente
por el valor de la columna titulo. Una vez seleccionada la fila en libro, tambien
es intuitivamente sencillo determinar en que fila de la tabla escritor estan los
datos que debemos tener en cuenta: se trata de la fila correspondiente a Eva
Condal, la autora del libro en cuestion. Para elegir las filas de libro y de escritor
que corresponde reunir, nos basamos en que hay un dato, el nombre del autor,
que esta presente en ambas tablas. Al reunir informacion que en la BD esta se-
parada en dos tablas, obtenemos un mayor detalle de informacion acerca del
libro: reunimos los datos presentes en libro con la informacion de su autor, que
esta presente en escritor.
La existencia de un dato en comun entre las tablas libro y escritor puede
observarse en su estructura. El nombre de columna nomAutor aparece en las
dos tablas. Mas aun, es el unico nombre de columna que se repite: ningun otro
nombre de columna de libro aparece en escritor y viceversa. El criterio usado
para reunir una fila de libro con una de escritor es la coincidencia en el valor de
la columna que aparece en ambas filas. En el ejemplo, las dos filas reunidas
coinciden en el valor de nomAutor, que es Eva Condal.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


216

G.7.21. Consulta de dos filas en reunion natural

Leer con Atencion

Como se describio en el apartado 7.3.4, la columna nomAutor en libro


puede considerarse como una referencia a la fila correspondiente en
escritor. Observese que nomAutor es la clave primaria de escritor,
por lo tanto, cada fila de libro podra estar relacionada con, a lo sumo,
una fila en escritor.

Esta situacion se repite frecuentemente en las bases de datos relacionales, sien-


do el criterio mas sencillo que se utiliza para reunir varias filas en una misma
consulta. Dentro de la teora de bases de datos relacionales, se define el con-
cepto de reunion natural de filas para describir estos casos.

Definicion 7.5.2. Se dice que dos filas de distintas tablas estan en reunion natural
Frecuentemente este concepto si y solo si, tienen los mismos valores para todas las columnas que aparecen en
aparece bajo el nombre natural ambas tablas. Para que dos filas de distintas tablas esten en reunion natural, la
join, su denominacion en ingles.
estructura de las tablas debe coincidir en al menos un nombre de columna.

El lenguaje SQL provee una forma sencilla de generar consultas que, en su resul-
tado, reunan filas de distintas tablas que estan en reunion natural. Recordemos la
forma general de las consultas segun lo descripto en los apartado 7.4.4 y 7.4.5,
o sea:
select < columnas > from < tabla > where < condicion >
order by < orden >;
Para incluir en la consulta filas en reunion natural que estan en distintas tablas,
debemos modificar la especificacion de la < tabla >. En lugar de incluir un so-
lo nombre de tabla, incluimos las dos tablas involucradas en la reunion natural,
poniendo las palabras natural join entre los nombres de tabla.
Para obtener, en una misma consulta, los datos sobre El cachalote contento
que estan separados en las tablas libro y escritor podemos ejecutar la siguiente
select titulo, anio, idioma, nomAutor, paisNacim, anioNacim
consulta from libro natural join escritor
where titulo = El cachalote contento;
En el grafico G.7.21 se muestra el resultado de esta consulta. La reunion natural
entre dos filas genera una sola fila en el resultado de la consulta, que reune los
datos que en la BD estan separados en las filas que se reunieran en la consulta.

El mecanismo por el que se obtiene una informacion mas detallada acerca de


un libro mediante la reunion natural con una fila de escritor puede aplicarse a
todas las filas de libro, pues escritor incluye datos para los autores de todos los
libros registrados en libro.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


217

G.7.22. Reunion natural todas las filas de libro

G.7.23. Consulta con la reunion natural de cada fila de libro

Para Ampliar

Al definir la estructura de la tabla libro puede especificarse que el valor


de nomAutor debe corresponder a un escritor registrado en escritor.
Esta caracterstica esta relacionada con el concepto de clave foranea,
mencionado en el apartado 7.3.4.

Esta situacion se describe en el grafico G.7.22.

El resultado de la consulta

select titulo, anio, idioma, nomAutor, paisNacim, anioNacim


from libro natural join escritor;

al no tener condicion sobre las filas de libro a incluir, realizara para cada fila de
libro la reunion natural con la fila correspondiente de escritor, obteniendose el
resultado que se muestra en el grafico G.7.23.

El uso de la reunion natural en una consulta puede combinarse con las va-
riantes de definicion de columnas y condiciones estudiadas hasta ahora.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


218

Ejemplo

Por ejemplo, podemos usar una columna calculada para incluir la edad
que tena el autor de cada libro de autor argentino cuando se edito el
libro:
select titulo, nomAutor, anio - anioNacim as edad
from libro natural join escritor
where paisNacim = Argentina;
o ttulo, autor y edad que tena el escritor, para los libros cuyo autor tena
menos de 40 anos al momento de ser editados:
select titulo, nomAutor, anio - anioNacim as edad
from libro natural join escritor
where anio - anioNacim <40;

Leer con Atencion

No se pueden usar los nombres asignados a las columnas calculadas


para referirse, en una condicion, al mismo calculo. Lamentablemente,
hay que repetir el calculo. Por eso la condicion de la consulta anterior es
anio - anioNacim <40 en lugar de edad <40.

Como ya mencionamos, el uso de la reunion natural en la consulta tiene el efecto


de reunir, en una unica fila en el resultado, datos que provienen de distintas tablas
en la BD. Destacamos que esto permite incluir operaciones que involucran datos
que estan separados en la BD, como es el caso de la resta anio - anioNacim.
Actividad 7

Obtener mediante consultas los datos solicitados.


Ttulo, nombre del autor y nacionalidad del autor, para los libros en
idioma espanol editados entre 1900 y 1999.
El apodo de los lectores que tienen libros en idioma espanol o
frances. En este caso hay que reunir cada fila de tieneLibro con
una fila de libro. No importa si se repite varias veces el mismo
nombre; para evitarlo comenzar la consulta con select distinct
en lugar de select.
Ttulo, apodo de lector, ano de edicion del libro, desde cuando el
lector tiene el libro, y cuantos anos hay entre la edicion del libro
hasta que el lector lo consiguio, para todas las filas de tieneLibro.
Ttulo de los libros editados despues de 1900 que sean de autores
nacidos antes de 1900.

7.5.4. Reuniendo mas de dos tablas


El concepto de reunion natural de filas puede extenderse a mas de dos tablas.
Observemos la tabla tieneLibro en la base de datos que usamos como ejemplo.
Cada fila de esta tabla representa el hecho de que un determinado lector tiene un
ejemplar de un libro. Por lo tanto, es razonable que cada fila de tieneLibro haga

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


219

G.7.24. Reunion natural entre filas de tres tablas

G.7.25. Consulta que une filas de tres tablas

referencia, de acuerdo con lo descrito en el apartado 7.3.4, a una fila de lector y


a una fila de libro. Observando la estructura de las tablas vemos que tieneLibro
comparte el nombre de columna titulo con libro, y tambien el nombre de columna
apodoLector con lector. Notamos que en ambos casos se trata de las claves
primarias de libro y lector respectivamente. Esta coincidencia de nombres de
columna permitira que cada fila de tieneLibro este en reunion natural con una fila
de libro y tambien con una fila de lector, como se muestra en el grafico G.7.24.
Se pueden construir consultas que aprovechen las dos reuniones naturales
presentes para brindar resultados que combinen datos presentes en las tres ta-
blas. Para cada lector que tiene un libro, se podran combinar datos del libro (ttulo,
ano de edicion, idioma, nombre del autor), del lector (apodo, nombre y apellido,
mail), y tambien la fecha desde cuando la persona posee el ejemplar del libro. Un
ejemplo es la siguiente consulta
select titulo, idioma, nombreYApe, mail, desde
from libro natural join tieneLibro natural join lector
order by titulo;
cuyo resultado se muestra en el grafico G.7.25. Cada fila de este resultado re-
presenta la union de datos que estan en tres filas, que en la BD aparecen en las
tres tablas mencionadas en la consulta.
En el resultado de la consulta que se muestra en el grafico G.7.25, hay tres
filas distintas que corresponden al libro La dama de las camelias, mientras que
el libro Cuarteles de invierno no aparece. Esto se debe a que La dama de las
camelias esta en reunion natural con tres filas distintas en tieneLibro, mien-
tras que Cuarteles de invierno no esta en reunion natural con ninguna fila en
tieneLibro; observar el grafico G.7.24.
Este fenomeno no debe ser interpretado como un error; cada fila del resultado
de la consulta corresponde a una combinacion de la reunion natural entre las tres

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


220

tablas.
Considerando la informacion que se esta modelando en la BD, hay tres lecto-
res que tienen ejemplares de La dama de las camelias, mientras que ninguno
tiene Cuarteles de invierno. Como cada fila en el resultado de la consulta co-
rresponde a un lector que tiene un libro, es correcto que un libro se repita tres
veces, mientras que el otro no aparezca.
Actividad 8

Aparecen todos los lectores en el resultado que se muestra en el grafi-


co G.7.25? Si aparecen todos, tratar de explicar por que; si hay alguno
que no aparece, intentar justificar las ausencias.

La multiplicidad que destacamos recien da lugar a distintos tipos de consulta,


por ejemplo, cuantos lectores tienen copias de cada libro, cual es el libro con
mas lectores, los ttulos de los libros de los cuales al menos dos lectores tienen
ejemplares, etcetera.
Para Ampliar

En esta breve introduccion no se describira como hacer estos tipos de


consultas. Puede consultarse material sobre consultas agrupadas, aso-
ciadas al uso de las palabras group by y having en consultas SQL.

Tambien pueden realizarse consultas del estilo de la que se muestra en el grafi-


co G.7.25, en el que se incluyan los libros de los cuales ningun lector tiene ejem-
plares, esto es, los que no aparecen referenciados en tieneLibro.
Para Ampliar

En esta breve introduccion no se describira esta posibilidad. El lector


interesado puede buscar material sobre joins parciales, asociados al uso
de las palabras left join y right join en consultas SQL.

Las variantes en la especificacion de columnas y condicion tambien pueden ser


utilizadas en las consultas que trabajan sobre la reunion natural de varias tablas.
Observese por ejemplo esta consulta:
select titulo, anio, left(idioma,2), nombreYApe, mail
from libro natural join tieneLibro natural join lector
where anio >1900
order by nombreYApe;
que muestra varios datos incluyendo las dos primeras letras del idioma del libro,
para cada lector y libro que tiene el lector, restringido a los libros editados luego
de 1900.

Terminemos este apartado observando que, dado que cada fila de la tabla
libro incluye una referencia a una fila de la tabla autor, tal como se describe en
el apartado 7.5.3, pueden armarse consultas en las que se hace una reunion na-
tural de las cuatro tablas incluidas en la BD que estamos usando como ejemplo.
Considerar la siguiente consulta:
select titulo, idioma, nomAutor, paisNacim
nombreYApe, desde
from libro natural join tieneLibro
natural join lector natural join escritor
order by titulo;

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


221

G.7.26. Consulta que une filas de cuatro tablas

cuyo resultado se muestra en el grafico G.7.26.


Actividad 9

Realizar un grafico analogo al grafico G.7.24, en el que se establezcan


todas las combinaciones de reunion natural entre las cuatro tablas. A
partir de este grafico, explicar por que Osvaldo Soriano no aparece entre
los resultados que se muestran en el grafico G.7.26.

Actividad 10

Obtener mediante consultas los datos solicitados.


Ttulo y ano de edicion de los libros que tiene Miguel Lopez.
Ttulo y ano de edicion de los libros de los cuales hay al menos un
lector que consiguio una copia en el ano 2007.
Ttulo del libro, nombre, apellido y cantidad de letras del mail, para
cada persona que tiene un libro, restringido a los libros cuyo idioma
es espanol o ingles, ordenado por el ttulo del libro.

Nombre, apellido y mail de las personas que tienen al menos una


copia de un libro de autor cubano.

Para Ampliar

La reunion natural es, como ya se dijo, la forma mas sencilla de reunir


datos que estan en distintas filas en la BD, en una unica fila en el resulta-
do de una consulta. Existen otros mecanismos para reunir filas. El lector
interesado puede consultar material que describa en forma detallada las
opciones existentes para construir consultas en el lenguaje SQL.

7.5.5. Otras actualizaciones


Finalizamos esta breve introduccion al lenguaje SQL describiendo las formas
mas sencillas para las operaciones de eliminacion y modificacion de filas.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


222

El comando delete permite eliminar filas de una tabla. La estructura general


de las expresiones correspondientes a este comando es
delete from < tabla > where < condicion >;
donde utilizaremos un unico nombre de < tabla >, y donde la < condicion >
admite las mismas variantes que las condiciones para las expresiones select
descritas en el apartado 7.4.4.
La forma mas segura de utilizar el comando delete es indicar un valor es-
pecfico para la columna que representa la clave primaria de la tabla. Por ejem-
plo, la siguiente expresion: elimina de la tabla libro a la fila que representa al libro
Pesca Pipo pesca.
delete from libro where titulo = Pesca Pipo pesca;

Si se utiliza una condicion mas abarcativa, pueden eliminarse varias filas con
una sola expresion. Por ejemplo
delete from libro where idioma = Espa~ nol;
elimina, si los datos de la tabla libro corresponden al grafico G.7.19, todas las
filas excepto las correspondientes a La dama de las camelias y Pigmallion.
Observamos que si hacemos referencia a un valor especfico sobre la clave
primaria, es seguro que no se eliminara mas de una fila ejecutando una expre-
sion. Podra tambien darse el caso en el que ninguna fila sea eliminada, porque
ninguna cumple con la condicion explicitada. Por ejemplo, considerando los libros
descritos en el grafico G.7.19,
delete from libro where titulo = Ulyses;
no eliminara ninguna fila, porque no hay ningun libro registrado cuyo ttulo sea
Ulyses.
El comando update permite actualizar filas de una tabla. La estructura gene-
ral de las expresiones correspondientes a este comando es
update < tabla > set < col > = < valor > where < condicion >;
donde corresponden para < tabla > y < condicion > las mismas consideracio-
nes que para delete. Por ejemplo, la siguiente expresion:
update libro set anio = 1992
modifica el ano de edicion
where titulo = El cachalote contento;
en la fila de libro correspondiente al libro El cachalote contento.
Al especificar el nuevo valor puede referenciarse al valor anterior. Por ejem-
plo, si queremos sumar dos anos al ano de edicion de un libro, podemos escribir
una expresion como la siguiente
update libro set anio = anio + 2
where titulo = El cachalote contento;

Leer con Atencion

Algunas herramientas de acceso a un SGBD podran prohibir la utiliza-


cion de expresiones delete y update que pudieran eventualmente apli-
carse a mas de una fila, o sea, cuya condicion sea distinta de igualdad
respecto de la clave primaria.
Consultar en la documentacion de la herramienta utilizada como levantar
dicha restriccion.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


223

Para Ampliar

Hemos descrito solamente las formas mas sencillas de los comandos


delete y update. Existen formas mas potentes, que permiten describir
operaciones de eliminacion y modificacion mas complejas. Consultar las
variantes de estos comandos en la documentacion del SGBD con el que
se desee trabajar.

Actividad 11

Realizar las siguientes actividades:


Eliminar el registro que indica que Romina Talli tiene el libro Pig-
mallion, referenciando el valor correspondiente de la clave primaria
de tieneLibro, que es una clave tecnica (ver apartado 7.3.4)
Modificar el registro que indica que Joaqun Perez tiene el libro Las
aventuras de Carozo, indicando que tiene el libro desde 2011.

Cambiar el pas de nacimiento de Ana Menseguez a Irlanda.


Agregar una fila en escritor que represente a Marco Denevi, indi-
cando que nacio en Peru en el ano 1922. Luego modificar el pas
de nacimiento a Argentina. Finalmente, eliminar la fila.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


224

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


225

Redes

Con el devenir de Internet las redes de computadoras ocupan un papel impor-


tante en el area de informatica. Por este motivo resulta imprescindible conocer
los aspectos fundamentales del area, aunque la profundidad con la que abor-
daremos los temas de esta unidad sera sumamente superficial. Como veremos
mas adelante, la mayora de los conocimientos giran en torno a un modelo idea-
do para razonar acerca de las redes de computadoras con mayor facilidad. Por
esta razon, en esta unidad veremos principalmente de que trata dicho modelo y
que tecnologas, equipos y herramientas intervienen en el mismo.

8.1. Redes de computadoras


Una red de computadoras es un conjunto de equipos y de programas que se co-
nectan entre s de alguna manera para comunicar datos y colaborar. Las redes
de computadoras permiten principalmente compartir y distribuir recursos, y co-
municar informacion tanto relativa enteramente a programas informaticos como
de personas. La entrega de la informacion debe ser consistente y confiable, por
lo que cada tecnologa y equipo se hara responsable en cierta medida de este
punto.

Definicion 8.1.1. Una red de computadoras, tambien llamada red de ordenado-


res, red de comunicaciones de datos o red informatica, es un conjunto de equipos
informaticos y software conectados con el fin de establecer una comunicacion de
datos.

Es importante tener en cuenta que al hablar de una red de computadoras, esta-


mos incluyendo cualquier conjunto de equipos (no solo computadoras de escrito-
rio, sino tambien servidores, conectores especializados, y actualmente podramos
tambien incluir telefonos inteligentes, tabletas y otros dispositivos moviles) y de
programas que se usen en dichos equipos para comunicar los datos. Estos equi-
pos y programas pueden estar hechos con tecnologas diferentes, con diferentes
convenciones y diferentes caractersticas. El objetivo de una red de computado-
ras es establecer una serie de normas y protocolos que todos los equipos y pro-
gramas deben respetar para poder establecer la comunicacion deseada.
Las redes de computadoras se pueden clasificar de acuerdo con diversas
nociones. Analizaremos por tanto estas nociones, y veremos los tipos mas im-
portantes de redes.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


226

8.1.1. Clasificacion de las redes


Existen diversas clasificaciones de las redes de datos, cada una enfocada a una
caracterstica particular de las mismas. Por el ambito en el que operan podemos
separarlas en:

Redes de area local o LAN (Local Area Network), disenadas desde el prin-
cipio para transportar datos en areas no tan extensas.

Redes de area extensa o WAN (Wide Area Network), disenadas para trans-
portar datos entre areas.

Para Reflexionar

Intente identificar ejemplos de redes que se ajusten a cada una de estas


categoras. Por ejemplo, si tomamos una analoga entre redes telefoni-
cas y redes de computadoras, una WAN sera la red de telefona de todo
un pas, mientras que una LAN sera una red interna telefonica de un edi-
ficio. Con base en esto, la red de computadoras de un cibercafe sera
una LAN o una WAN? Y una red que conecte a todas las computadoras
de todas las universidades del planeta?

Para Ampliar

Existen dos tecnologas muy utilizadas hoy da en lo que respecta a re-


des LAN. Una de ellas es el protocolo Ethernet, utilizado para comunicar
computadoras por cable. La otra es WLAN, utilizada como protocolo de
comunicacion va WI-FI. Presentaremos mas protocolos a medida que
avancemos en esta unidad.

Las redes WAN fueron disenadas en principio para transportar voz. De esto se
desprende que usualmente son servicios contratados a operadoras importantes.
Dado que los datos recorren grandes distancias se suele optimizar el diseno de
estas redes para reducir costos. Hay que tener en cuenta que muchas de ellas
se realizan va satelite. Por el contrario, las redes LAN son simplemente redes
implementadas para un ambito mas reducido, como puede ser una red domestica
o la red interna de una empresa.
Por otra parte, podemos separar las redes por la forma en que se comunican:

Redes broadcast, donde una computadora central distribuye informacion a


muchas otras computadoras.

Redes punto a punto, donde existe una comunicacion de computadora a


computadora de manera individual.

Actividad 1

Dada esta otra categorizacion de redes, de ejemplos de las mismas.

Estas dos nociones de tipo de comunicacion son bien sabidas en la vida cotidia-
na. Por ejemplo, una red broadcast es la television por cable, y una red punto a
punto es una llamada telefonica convencional. En las redes broadcast la informa-
cion es enviada a todos los nodos de la red, aunque solo interese a unos pocos;

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


227

en cambio, en las comunicaciones punto a punto la informacion solo se enva al


nodo al cual va dirigida. Por esta razon, en las redes broadcast el medio suele
estar compartido.
Para Reflexionar

Para entender un poco mejor como una comunicacion puede utilizar un


medio compartido por muchas otras comunicaciones imagine como fun-
ciona la radio, o incluso una sala en donde existan muchas personas
hablando y el medio sea justamente el aire que las rodea. Se imagi-
na que problemas pueden surgir por tener que compartir el medio de
comunicacion? Imagina como pueden solucionarse estos problemas?
Piense ademas en los problemas de seguridad que podran encontrarse
con respecto a la confidencialidad de la informacion.

Cabe destacar que los tipos de clasificaciones que realicemos sobre redes no
son excluyentes entre s, por lo que podemos tener redes broadcast LAN, redes
punto a punto WAN, por dar algunos ejemplos.

8.1.2. Redes cliente-servidor y redes punto a punto


Las clasificaciones mencionadas se referan a los equipos involucrados en la red,
en tanto su distribucion fsica o los medios de comunicacion que utilizaban. Una
forma de clasificacion mas orientada a las aplicaciones que se ejecutan sobre
redes es la de redes cliente-servidor. Las redes cliente-servidor son aquellas en
las que los nodos de la red pueden ser separados en servidores, que son las
computadoras que disponen de recursos, y clientes, que realizan peticiones a los
servidores. Por esta razon se dice que es un modelo centralizado.
En este modelo el cliente posee un rol activo, dado que son estos los que ge-
neran peticiones a los servidores. En otras palabras, el modo de funcionamiento
es el siguiente:

el cliente realiza una peticion al servidor y espera la respuesta;

el servidor recibe la peticion, procesa los datos y enva la respuesta.

Ejemplo

La mayora de los servicios de Internet son de tipo cliente-servidor. Por


ejemplo, cuando deseamos visitar una pagina, la misma esta alojada en
un servidor, por lo que nuestro navegador la solicita para su posterior
visualizacion. Otros ejemplos incluyen juegos en lnea, acceso a bases
de datos remotas, servidores de correo, etcetera.

Actividad 2

Enumere algunas ventajas y desventajas de este tipo de redes.

Sin embargo, aunque los servicios sean mayormente de tipo cliente-servidor, las
comunicaciones entre computadoras son punto a punto, en donde la red no fun-
ciona con clientes y servidores fijos, sino que cada computadora que la compo-
ne actua simultaneamente como cliente y servidor. Esto permite el intercambio

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


228

directo de la informacion entre las computadoras de dicha red. La descentrali-


zacion de este tipo de red hace que escale con mayor rapidez (o sea, admita
mayor numero de maquinas sin que la complejidad de su logica aumente), sea
mas robusta, al no depender de un unico grupo de nodos para mantenerla, y
principalmente que los costos de los recursos necesarios sean repartidos entre
las distintas maquinas, haciendo que por ejemplo el ancho de banda (la cantidad
de informacion que circula entre cada par de maquinas) sea optimizado.
Actividad 3

Contraste las caractersticas que poseen las redes punto a punto y las
de arquitectura cliente-servidor.

Otras caractersticas a tener en cuenta son la clasificacion de los enlaces y la


topologa de la red (o sea, que maquinas se conectan con cuales).

Redes punto a punto y clasificacion de enlaces


En una red punto a punto los enlaces pueden ser de distintos tipos:
Simplex Es cuando la transmision se da en un solo sentido (no se responde el
mensaje).
Semi-duplex Es cuando la transmision puede darse en ambos sentidos pero no
al mismo tiempo.
Duplex Es cuando la transmision se da en ambos sentidos y de forma simultanea.
Esta clasificacion puede razonarse facilmente entablando una analoga con las
comunicaciones telefonicas. Una comunicacion Simplex podra ser el envo de un
mensaje grabado, donde la comunicacion finaliza al momento de enviar el men-
saje (no es posible contestar el mensaje en esa misma comunicacion). Para el
caso de semi-duplex puede pensarse en los walkie-talkie, dado que es posible
entablar una comunicacion en ambos sentidos pero se deben turnar. Y para el
ultimo claso, Duplex, una comunicacion telefonica como las que solemos soste-
ner a diario.

Topologas de redes
Por ultimo, las redes ademas pueden estar dispuestas de diversas maneras. To-
das pueden estar conectadas a una central y esa central distribuir la informacion,
pueden estar conetactadas a un medio comun (un cable que atraviesa a todas),
etcetera. No cubriremos en esta unidad las ventajas o desventajas de las distin-
tas topologas de redes de computadoras; en el grafico G.8.1 pueden observarse
algunas.
No obstante, en la mayora de los casos se escoge una topologa jerarquica
en distintos niveles (sobre esto avanzaremos mas adelante).

8.2. Modelo de capas


La interconexion de computadoras es un problema tecnico de complejidad ele-
vada. Requiere el funcionamiento correcto de equipos (hardware) y programas
(software) desarrollados por diferentes equipos humanos, con diferentes tecno-
logas y diferentes convenciones. Cuando las cosas no funcionan es muy com-
plejo detectar cual de las partes es la responsable.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


229

G.8.1. Ejemplos de topologas

Para resolver este complejo problema se decidio dividirlo en partes. En la


teora de las comunicaciones, las partes se llaman capas y cada una tiene una Esto debera sonarle similar a lo
funcion bien definida. De esta manera se diseno un modelo de capas para des- que vio en las unidades anteriores.
cribir el funcionamiento de las redes de forma modular, con el fin de realizar cam-
bios de manera sencilla y entender su funcionamiento completo. Este modelo de
capas es a su vez denominado modelo de referencia, ya que es la base de todo
analisis en lo que respecta a redes de computadoras. El modelo de capas mas
conocido es el llamado modelo OSI (del ingles Open Systems Interconnection,
Interconexion de Sistemas Abiertos); sin embargo, la Internet utiliza mayormente
otro modelo conocido como TCP/IP. Desarrollaremos ambos en proximos apar-
tados.
El modelo de capas se basa en los siguientes principios:
Una determinada capa ofrece servicios a su capa de nivel superior.
Una capa superior solo utiliza los servicios provistos por su capa inferior
mas proxima.
La comunicacion entre capas se realiza mediante una interfaz.
Otro concepto visto en unidades
Cada capa se comunica con la capa equivalente en el otro sistema utilizan- anteriores.
do un protocolo caracterstico de esa capa.
Definicion 8.2.1. Un modelo de capas es un modelo conceptual de organizacion
de las funciones de comunicacion de una red, principalmente representado como
una pila de distintas capas, cada una con funcionalidades y responsabilidades
bien definidas, y de alguna manera jerarquizadas.
Puede observarse un ejemplo de comunicacion en el modelo de capas en el
grafico G.8.2.
Definicion 8.2.2. Un protocolo es el conjunto de reglas que establecen la forma
en la que se comunican capas del mismo nivel en sistemas diferentes.
Definicion 8.2.3. Una interfaz en redes de computadoras es el conjunto especfi-
co de servicios que cada capa le brinda a la inmediatamente superior, establen-
ciendo la forma especfica mediante la cual se comunican capas contiguas en la
pila de capas.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


230

Capa Comunicacin Virtual


Argentina Brasil

4 Presidente Presidente

3 Traductor Traductor
3

2 Secretaria Secretaria
Comunicacin Real

1 Fax Fax

G.8.2. Ejemplo de comunicacion como un modelo de capas

El conjunto de protocolos que interoperan en todos los niveles de una arquitectura


dada se conoce como stack de protocolos. Actualmente todas las arquitecturas
El termino ingles stack significa pi- de red se describen utilizando un modelo de capas. El mas conocido es el de-
la, o sea, el resultado de apilar co- nominado Modelo de Referencia OSI (Open Systems Interconnect) de ISO, que
sas.
tiene 7 capas.
Para sumarizar, los principales beneficios de un modelo de capas son:

Sencillez Dado que hace abordable el complejo problema de la comunicacion


entre computadoras.

Modularidad Puesto que permite realizar cambios con relativa facilidad a una
de sus partes sin afectar al resto.

Compatibilidad Ya que la comunicacion entre dos entidades de una capa puede


realizarse independientemente de las demas.

Actividad 4

Con base en lo explicado hasta aqu intente describir por que un modelo
de capas posee los beneficios mencionados. Puede relacionarlo con lo
que sabe de unidades anteriores.

8.2.1. Modelo OSI


El modelo OSI es el modelo estandar para describir la comunicacion entre redes
de computadoras. Fue definido entre 1977 y 1983 por la ISO para promover la
creacion de estandares independientes de los fabricantes comerciales. La capa
de aplicacion es la que ve el usuario final, ya que muestra la informacion recibida
a traves de las aplicaciones que utilizamos a diario (navegadores, clientes de
correo, procesadores de texto, etcetera).

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


231

Argentina Protocolo Brasil


Medicina
Mdico Mdico
Interfaz
Espaol Portugus
Idiomas
Secretaria Secretaria

Teclado Teclado
E-Mail
Computadora Computadora

G.8.3. Ejemplo de interfaces y protocolos en un modelo de capas

7
Capa de aplicacin

6
Capa de presentacin

5
Capa de sesin

4
Capa de transporte

3
Capa de red

2
Capa de enlace

1
Capa Fsica

G.8.4. Capas del modelo OSI

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


232

8.2.2. Modelo TCP/IP


Si bien el modelo OSI es utilizado a nivel teorico, no es el que predomina en
las implementaciones de redes de computadoras actuales. Los protocolos y tec-
nologas utilizados actualmente forman parte del llamado modelo TCP/IP. Este
modelo tambien nacio por la necesidad de interoperar redes diversas, pero a dife-
rencia del modelo OSI primero surgieron los protocolos TCP/IP antes de haberse
definido de forma acabada el modelo. Por que se presenta el modelo OSI si
no es el preponderante? Porque el modelo OSI fue disenado para razonar sobre
redes de computadoras, y es mas modular que el modelo TCP/IP, que en cambio
surgio a partir de la solucion practica de los problemas que se iban presentando.
A grandes rasgos, el modelo OSI tiene 7 capas y el modelo TCP/IP solo tiene 4
capas, lo que significa que en este ultimo algunas de las capas teoricas prescri-
tas por el modelo OSI se encuentran superpuestas y la division de incumbencias
es menos precisa.
La principal razon por la que el modelo OSI no es utilizado globalmente en
redes de computadoras actuales radica en que las implementaciones de proto-
colos que ofrece son menos eficientes que las del modelo actual. Por otro lado,
los dispositivos disenados para TCP/IP resultaron ser ademas baratos dado que
las companas hicieron un gran esfuerzo para que as lo sea. De esta manera, en
TCP/IP los productos aparecan rapido y estaban altamente probados (pues los
usaba mucha gente). Por todas estas razones suele decirse que el modelo OSI
es academico mientras que el modelo TCP/IP es practico.

8.2.3. Modelo hbrido


Si bien el modelo OSI esta muy bien dividido, para los alcances de la materia nos
bastara con razonar acerca de 5 de las 7 capas, como puede observarse en el
grafico G.8.5, donde la capa de aplicacion incluye las de sesion y presentacion.
Este modelo hbrido entre TCP/IP y OSI a su vez nos permitira abordar tecno-
logas del primero de ambos, pero desde un modelo mejor adaptado a estas.

8.2.4. Protocolos
Como dijimos, un protocolo es un conjunto de reglas que prescriben la comunica-
cion entre dos pares de componentes en dos extremos de la red. Los protocolos
definen diversas caractersticas de la comunicacion entre dos capas de un mismo
nivel:

La sintaxis de los mensajes.

El significado de los campos de informacion.

La forma en que se envan los mensajes y la respuesta esperada.

Normalmente todo protocolo requiere el envo de algunos mensajes especiales o


informacion de control adicional a la que se transmite. Generalmente esto se
realiza anadiendo encabezados, y a veces tambien un terminador, al paque-
te a transmitir. La informacion de control reduce el desempeno, y supone un
overhead, pero alguna informacion de control resulta necesaria. Puesto que ca-
Es un termino utilizado en informa- da capa anade su propia informacion de control (encapsulacion). Cuantas mas
tica para describir el retraso de un capas tiene un modelo mas overhead se introduce.
proceso por tener que realizar otros
procesos auxiliares.
Aunque existen muchos fabricantes que disenan distintos dispositivos, todos
ellos se guan bajo ciertos estandares. Estos estandares pueden ser de facto

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


233

5
Capa de aplicacin

4
Capa de transporte

3
Capa de red

2
Capa de enlace

1
Capa Fsica

G.8.5. Capas del modelo hbrido

Cliente Protocolo Servidor

HTTP
Aplicacin Aplicacin
Interfaz
Sockets Sockets
TCP
Transporte Transporte

IP
Red Red

Winsock Winsock
IEEE 802.3
Enlace Enlace

IEEE 802.3
Fsica Fsica

G.8.6. Acceso a un servidor Web desde un cliente en una LAN Ethernet

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


234

(impuestos por empresas) o impuestos por organizaciones de estandares, tales


como ISO, IEEE, ANSI, W3C, etc. El modelo OSI, como destacamos anterior-
mente, fue disenado por la organizacion de estandares ISO, bajo el nombre de
ISO 7498.

8.2.5. Tipos de servicios


Existen dos tipos principales de servicios: los orientados a conexion y los no
orientados a conexion. Un servicio orientado a conexion (CONS) establece el
canal antes de enviar la informacion, como por ejemplo, una llamada telefonica.
Un servicio no orientado a conexion (CLNS) enva los datos directamente, sin
necesidad de controlar si llegaron a destino. Un ejemplo tpico es la television.
En el servicio orientado a conexion (CONS),
se respeta el orden de los paquetes,
se mantiene la misma ruta o camino para todos los paquetes,
los paquetes no necesitan llevar la direccion de destino, y
si el canal se corta la comunicacion se interrumpe.
Ejemplos de servicios orientados a conexion son: Frame Relay, ISDN, Telnet,
TCP.
En el servicio no orientado a conexion (CLNS)
no se respeta el orden,
cada paquete ha de llevar la direccion de destino,
la ruta puede variar para cada paquete, y
la red resulta mas robusta, ya que si una ruta queda inservible se pueden
usar otras.
Ejemplos de servicios no orientados a conexion son UDP, DNS e IP.

8.3. Capas del Modelo OSI


En este apartado describiremos algunos protocolos y dispositivos de las capas
que consideramos mas importantes a tener en cuenta, fundamentalmente las ca-
pas de aplicacion, de red y de enlace. Nos concentraremos mayormente en estas
tres dado que esta unidad no representa un estudio exhaustivo de la implemen-
tacion y mantenimiento de redes y solo pretende proveer una mirada general del
tema.

8.3.1. Capa de aplicacion


La capa de aplicacion proporciona principalmente protocolos para la comunica-
cion entre aplicaciones que manipula el usuario. Define los protocolos que uti-
lizan las aplicaciones para intercambiar datos, como correo electronico (POP y
SMTP), de transferencia de archivos (FTP) y paginas web (HTTP). Todos estos
protocolos utilizan el modelo Cliente/Servidor.
Cabe aclarar que el usuario normalmente no interactua directamente con el
nivel de aplicacion. Suele interactuar con programas que a su vez interactuan con
el nivel de aplicacion y que ocultan la complejidad subyacente. As por ejemplo

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


235

un usuario no manda una peticion con el comando GET propio del protocolo HTTP
para conseguir una pagina web, ni lee directamente el codigo que define a una de
estas paginas, que es codigo en lenguaje HTML (que sera visto en subapartados
siguientes). El usuario interactua con un navegador web, un cliente de correo o
una aplicacion de chat, y estos programas son los que utilizan los protocolos de
esta capa con el fin de comunicarse entre s.
En suma, protocolos de esta capa son:

FTP (File Transfer Protocol - Protocolo de transferencia de archivos) para trans-


ferencia de archivos.

DNS (Domain Name Service - Servicio de nombres de dominio) para identifica-


cion de los destinos de los mensajes.

DHCP (Dynamic Host Configuration Protocol - Protocolo de configuracion dinami-


ca de anfitrion) para conectar maquinas a la red de manera dinamica.

HTTP (HyperText Transfer Protocol) para acceso a paginas web.

POP (Post Office Protocol) para leer correo electronico.

SMTP (Simple Mail Transport Protocol) para enviar correo electronico.

SSH (Secure SHell) para acceder a equipos remotos en modo TELNET.

No veremos la definicion exacta de todos estos protocolos, pero a continua-


cion explicaremos los detalles mas importantes de los principales protocolos de
esta capa.

Protocolo HTTP

El protocolo HTTP es uno de los mas importantes de esta capa dado que los usua-
rios de internet lo utilizan constantemente. Significa Hypertext Transfer Protocol,
y define un grupo de comandos para pedir paginas web y enviar datos hacia las
mismas. Actualmente tambien existe un protocolo llamado HTTPS, que imple-
menta una version mas segura, donde los datos que viajan estan encriptados.
Algunos comandos del protocolo son GET, POST, HEAD, CONNECT. Cuando un
cliente establece el inicio de una comunicacion con un servidor HTTP, el primero
enva estos comandos al segundo, de tal manera que se establece un dialogo
entre ambos: cliente pidiendo recursos y el servidor otorgandolos. Todo recurso
transmitido por este protocolo se identifica por una URL. Estos recursos pueden
ser archivos, imagenes, paginas web, entre otros.
Actividad 5

Buscar en la web recursos de estos tres tipos y conseguir la URL que


los identifica.

El protocolo HTTP es sin estado, es decir, no guarda ninguna informacion sobre


conexiones anteriores. Si fuese necesario mantener estado se utilizan pequenas
piezas de informacion denominadas cookies. Las cookies representan informa-
cion que un servidor puede almacenar en el sistema cliente por tiempo indeter-
minado. Esto le permite a las aplicaciones web construir la nocion de sesion, y
tambien permite rastrear usuarios, para saber quien esta conectado a la pagina
por ejemplo.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


236

Para Reflexionar

Las cookies son utilizadas tambien para almacenar datos de los usua-
rios con respecto a publicidades. Esto es as porque contienen muchas
veces informacion clave sobre el comportamiento de la persona mien-
tras navega. Considere las implicaciones que pueden tener las cookies
para su seguridad ahora que sabe para que son utilizadas.

Ilustraremos todo esto con un ejemplo sencillo: realizaremos la peticion de la


pagina del buscador Google con la aplicacion web mencionada.
Actividad 6

Abra la siguiente pagina en un navegador y siga las instrucciones del


ejemplo detallado a continuacion.

http://web-sniffer.net/
Introduzca la URL del buscador (www.google.com.ar) en la parte de
HTTP(S)-URL. Presione submit y se completara la informacion relativa
al servicio. Podemos ver que cuando realizamos un pedido HTTP
debemos indicar que version del protocolo utilizaremos y que comando
deseamos enviar. En este caso se encuentra configurado por defecto el
comando GET.
Podemos ver la informacion de Request (pedido del cliente) y de
Response (respuesta del servidor). Dentro del pedido podemos ver el
navegador con el que realizamos la consulta, el destino (Host) y diver-
sas configuraciones de idioma y codificacion de la informacion. Dentro
de la respuesta el servidor nos retorna un mensaje de estado. Si el ser-
vidor de Google nos responde correctamente el estado debera ser OK.

Existen otros estados que detallan solicitudes incorrectas, problemas con el ser-
vidor, etcetera. Todos se encuentran numerados. Ademas del estado el servidor
nos retorna contenido, indicando que tipo de contenido posee la informacion que
requiere el cliente. En este caso es una pagina web por lo que el contenido es
texto HTML. El servidor que sirve al cliente tambien enva informacion adicional
Este protocolo de descripcion de para poder visualizarla correctamente, que a nuestros fines no analizaremos. To-
paginas sera tratado en subaparta- da esta informacion que acabamos de nombrar forma parte del encabezado de
dos siguientes.
la respuesta del servidor, y el cuerpo de dicha respuesta, que es la pagina web
que nos entrega, forma parte del cuerpo del mensaje. En el cliente que utilizamos
para hacer el pedido podemos ver el contenido principal en el apartado content.
Ese contenido cuando se realiza un pedido de forma tradicional con un navega-
dor es interpretado para ser presentado de la forma que habituamos a diario.

Protocolos SMTP, POP e IMAP

Los protocolos SMTP, POP e IMAP son utilizados para el manejo de correo electroni-
co. El protocolo SMTP es un protocolo de transferencia de correos, tanto para
envo desde el cliente al servidor de correo, como entre servidores de correos
que distribuyen entre s la informacion. Pero no provee forma de acceder luego
a la casilla de correo para poder acceder a los mails. Esto ultimo lo permiten los
protocolos POP e IMAP, que funcionan de distinta manera.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


237

Todos estos protocolos al igual que HTTP tambien poseen diversos coman-
dos. Particularmente SMTP posee comandos que permiten ir definiendo un correo
propiamente dicho, y uno para finalizar y que el servidor procese la consulta.
El siguiente ejemplo constituye un dialogo tpico entre una maquina cliente (c)
y un servidor (s):

S: 220 Servidor ESMTP


C: HELO miequipo.midominio.com
S: 250 Hello, please to meet you
C: MAIL FROM: <yo@midominio.com>
S: 250 Ok
C: RCPT TO: <destinatario@sudominio.com>
S: 250 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: Subject: Campo de asunto
C: From: yo@midominio.com
C: To: destinatario@sudominio.com
C:
C: Hola,
C: Esto es una prueba.
C: Hasta luego.
C:
C: .
S: 250 Ok: queued as 12345
C: quit
S: 221 Bye

Esta es la manera en la que actua un cliente de correo en su implementacion


interna. La interfaz grafica de esos programas solo es una forma de hacer mas
amigable este proceso para las personas, proveyendo una capa de abstraccion
que les permita concentrarse en las ideas que desean transmitir, y no en la re-
presentacion subyacente.
Los protocolos POP e IMAP por el contrario permiten acceder a los mails que
son registrados en nuestras casillas de correo. Su funcionanmiento difiere en que
mediante POP el correo cuando es tomado de la casilla es eliminado de la misma,
no encontrandose luego en consultas posteriores. En otras palabras, cada vez
que usamos POP y retiramos un mail, dicho mail es borrado del servidor en donde
se encuentra alojado y es descargado en la maquina en la que lo estemos leyen-
do. IMAP por el contrario permite dejar el correo recibido en la casilla y al mismo
tiempo descargarlo en nuestras computadoras sin mayores problemas.

Protocolo DNS

Si bien cada recurso de la web es identificado por una URL, la direccion del servi-
dor al que nuestra computadora realiza el pedido se identifica en realidad por una
direccion de IP. Una IP es una identificacion de una maquina, pero numerica. El
protocolo DNS es el encargado de traducir nombres, llamados nombres de domi- Si bien este concepto no es propio
nios (URLs) para obtener la IP correspondiente del servidor al que el navegador de la capa de aplicacion sino de la
capa de red del modelo OSI, el pro-
debe realizar el pedido. Nosotros, los humanos, no utilizamos directamente estas tocolo DNS se vale de este concepto
IP (aunque podramos) porque nos es mas facil recordar nombres significativos para operar.
que numeros sin ningun significado aparente. Por otra parte, la direccion numeri-
ca podra cambiar por muchas razones, sin que tenga que cambiar el nombre.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


238

G.8.7. Consulta de nombre de dominio

Como todo protocolo de esta capa, existen clientes que realizan peticiones,
y servidores que ofrecen respuestas a dichas peticiones. El cliente basicamen-
te pregunta Que direccion IP corresponde a nombre.dominio? Esta pregunta
se deriva al servidor de DNS que opera en la zona del cliente. Cada zona de
autoridad abarca al menos un dominio y posiblemente sus subdominios, si es-
tos ultimos no son delegados a otras zonas de autoridad. Para resolver estos
pedidos los servidores de DNS poseen una base de datos en donde registran
todas estas traducciones y delegaciones a otros servidores.

Ejemplo

Tomaremos como ejemplo www.unq.edu.ar. La parte de ar (la que


esta mas a la derecha) es la parte mas general de la URL. Cada nombre
encontrado mas a la izquierda vuelve mas especfica a la URL. El proto-
colo DNS va tomando desde lo mas general a lo especfico para resolver
la consulta. La zona de autoridad de ar en este caso es el servidor de
DNS que le corresponda a la Argentina (tecnicamente primero la consulta
es tomada por alguno de los servidores internacionales y luego pasada
al servidor argentino). Luego la consulta es pasada al servidor de DNS
encargado de realizar consultas para dominios edu, que debera conte-
ner la respuesta de que IP posee la pagina de la UNQ en este caso. La
parte final, www, simplemente dice que nos estamos refiriendo a un recur-
so web, que especficamente debe ser manejado por un servidor HTTP
que posee la UNQ.

Como podemos observar los servidores de DNS mantienen una organizacion


jerarquica. En otras palabras, existen servidores de niveles mas bajos que reali-
zan consultas mas concretas y locales, y servidores globales que realizan dele-
gaciones a servidores mas especficos. Con el ejemplo anterior podemos notar
claramente esta jerarquizacion entre servidores, cada uno pasando la consulta al
mas especfico que debera tener la respuesta. En el grafico G.8.7 se puede ver
de forma ilustrada otro ejemplo, esta vez pidiendo la IP de Wikipedia. El protoco-
lo no solamente es utilizado para pedir paginas web: el ejemplo del grafico G.8.8
muestra como el navegador, queriendo enviar un correo al destinatario, pide al
servidor de DNS local a que IP enviar el correo deseado. Esto demuestra que no

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


239

G.8.8. Otro ejemplo de consulta de nombre de dominio

solo las URL de tipo www son las unicas traducidas, y por el contrario cualquier tipo
de nombre de dominio es traducido por este protocolo.
Por ultimo debemos destacar que muchas veces la consulta no viaja hasta
el servidor mas especfico sino que es respondida por un servidor mas general
que posee guardada la respuesta. Esto se debe a que todo el viaje de informa-
cion y delegacion entre servidores es costosa, y en muchos casos para consul-
tas realizadas frecuentemente al servidor le conviene mantener guardadas estas
respuestas de manera local.

8.3.2. Capa de transporte


La capa de transporte es la encargada de la correcta transferencia de datos entre
aplicaciones que se comunican en distintas computadoras. En otras palabras, la
tarea de esta capa es proporcionar un transporte de datos confiable y economico
de la maquina de origen a la maquina destino, independientemente de la red
fsica sobre la que trabajen estas computadoras.
Para lograr este cometido, la informacion es fragmentada en porciones de
informacion llamadas paquetes. Cada paquete posee informacion de control so-
bre el cuerpo de la informacion a enviar. Con esto se logra indentificar desde
que aplicacion se enva la informacion y hacia cual se desea comunicar.
Como podemos notar, en nuestras computadoras poseemos diversas aplica-
ciones corriendo en simultaneo, y muchas de ellas estan realizando solicitudes
por la red para distintos propositos. Esta capa es la que resuelve como organizar
la informacion recibida y transmitida de tal manera que llegue a la aplicacion co-
rrespondiente. Esto se conoce con el nombre de multiplexion de conexiones, que
es la forma de convertir cada conversacion dinstinta entre aplicaciones en una
conexion distinta e identificable.
Para poder identificar unvocamente a un emisor y receptor se utiliza nue-
vamente el concepto de IP, pero se anade un dato mas, llamado puerto. Las
computadoras proveen una cantidad bastante grande de puertos que las apli-
caciones utilizan para recibir y enviar informacion. Se puede pensar un puerto
como un buzon que el sistema operativo de la computadora provee con el fin
de permitir a una aplicacion comunicarse por la red. La union de una IP con
un puerto se conoce con el nombre de socket. De esta manera se asignaran
dos pares de sockets a cada paquete enviado por la red. Un socket sera el del
emisor y otro el del receptor. La parte de IP identificara a la maquina y la parte Si bien esto no es as para todos los
del puerto a la aplicacion de dicha maquina. casos elegiremos pensar que s.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


240

Para implementar lo anteriormente descrito para esta capa podemos encon-


trar dos tipos de protocolos. Uno se denomina TCP, y se dice que es orientado
a conexion; el otro es UDP, que por el contrario es no orientado a conexion. Ser
orientado a conexion significa que es de vital importancia comprobar que la infor-
macion esta llegando a destino de la forma correcta. Pero si esto no nos interesa,
podemos enviar la informacion sin realizar estos chequeos. Elegir entre un pro-
tocolo u otro dependera de cada aplicacion y del tipo de servicio que ofrecen.
Por ejemplo, una aplicacion que pide la hora del sistema por internet utiliza para
comunicarse un protocolo UDP, dado que si la hora llego mal formada es posible
volver a pedirla. Un ejemplo de un servicio que utiliza TCP es HTTP, dado que
las paginas s deseamos comprobar que llegan a destino de la forma espera-
da. Una ventaja de elegir UDP es que el envo de la informacion se vuelve mas
eficiente, dado que requerimos menos informacion de chequeo. Para casos en
donde esto tambien es muy importante, se suele utilizar por ende este protocolo
de transporte.
Actividad 7

Buscar por internet al menos 2 ejemplos mas de servicios o aplicaciones


que utilicen TCP y UDP para transportar datos.

8.3.3. Capa de red


En la capa enterior la informacion es fragmentada en paquetes donde se iden-
tifican emisor y receptor, en esta capa la informacion es encaminada a destino.
De esto se encarga la capa de red, que identifica el enrutamiento existente entre
una o mas redes. El objetivo de la capa es hacer que los datos lleguen desde el
origen al destino, aun cuando ambos no esten conectados directamente, sino a
traves de algunas maquinas que actuan de intermediarias.
Una caracterstica adicional de esta capa es que no le concierne el tipo de
informacion transmitida, solo se encarga de encontrar el camino para guiarla a
destino.
En esta capa los protocolos se dividen en dos grupos:

Enrutables, que son aquellos que viajan junto con la informacion. Dentro de
estos podemos encontrar al protoclo IP.

De enrutamiendo, que son los que permiten seleccionar que ruta tomara la
informacion. Cada protocolo en este caso elige una forma distinta de resol-
ver este problema, y entre ellos podemos nombrar RIP, IGRP, OSPF, BGP.

Los dispositivos que facilitan la tarea de enrutar paquetes se denominan rou-


ters. Estos dispositivos realizan un direccionamiento logico, es decir, determinan
la ruta de los datos hasta su receptor final. Entre una maquina y otra pueden
existir muchos routers. En este caso cada router pasa informacion al proximo,
y el ultimo sabra a que maquina corresponde cierta informacion. Para esto se
utiliza por ejemplo la direccion IP, que mencionamos tambien en el apartado de
capa de transporte.
Las tecnicas de enrutamiento suelen basarse en el estado de la red, que es
dinamico, por lo que las decisiones tomadas respecto a los paquetes de la misma
conexion pueden variar segun el instante de manera que estos pueden seguir
distintas rutas. El problema, sin embargo, consiste en encontrar un camino optimo
entre un origen y un destino. La seleccion optima de este camino puede tener
diferentes criterios: velocidad, retardo, seguridad, regularidad, distancia, longitud

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


241

media de las colas, costos de comunicacion, etc. Los routers se encargan de


esta labor, utilizando alguno de los protocolos de enrutamiento mencionados.
Algo que vara la forma de enrutar los paquetes es si la comunicacion entre
las maquinas es orientada a conexion o no. Si fuese no orientada a conexion,
cada paquete debe llevar la direccion destino, y con cada uno, los nodos de la
red deciden el camino que se debe seguir. En caso contrario, para conexiones
orientadas a conexion, solo el primer paquete de cada mensaje tiene que llevar
la direccion destino. Con este paquete se establece la ruta que deberan seguir
todos los paquetes pertenecientes a esta conexion. Cuando llega un paquete que
no es el primero, se identifica a que conexion pertenece y se enva por el enlace
de salida adecuado, segun la informacion que se genero con el primer paquete y
que permanece almacenada en los routers.
Para Reflexionar

Por que para las comunicaciones orientadas a conexion solo es nece-


sario que la direccion de destino se encuentre en el primer paquete?

Otro dispositivo que tambien actua en esta capa es el firewall. Se trata de un


dispositivo o conjunto de dispositivos configurados para permitir, limitar, cifrar y
descifrar el trafico de paquetes entre redes, con base en un conjunto de normas
y criterios que permiten o no el acceso. Todos los mensajes que entren o salgan
de una red mediada por un firewall son examinados y bloqueados cuando no
cumplen los criterios de seguridad especificados. Pueden ser implementados en
hardware o software, o una combinacion de ambos.
Actividad 8

Investigue en la red cuales son los distintos tipos de firewalls. Algunos


firewalls actuan en otras capas que no sean la de red? Justifique su
respuesta.

Por ultimo, en esta capa se realizan tambien controles de congestion de trafico.


Cuando en una red, un nodo recibe mas trafico del que puede procesar, se puede
dar una congestion. El problema es que una vez que se da una congestion en un
nodo, el problema tiende a extenderse por el resto de la red. Por ello, hay tecnicas
de prevencion y control que se pueden y deben aplicar en el nivel de red.

8.3.4. Capa de enlace y capa fsica


Mientras que en la capa de red exista un direccionamiento logico, en la capa de
enlace el direccionamiento es fsico. Recibe peticiones de la capa de red y se
encarga de transmitir la informacion segun los medios fsicos que conformen la
red. El objetivo de la capa de enlace es conseguir que la informacion fluya, libre
de errores, entre dos maquinas que esten conectadas directamente. Para lograr
este objetivo tiene que montar bloques de informacion (llamados tramas en esta
capa), dotarles de una direccion de capa de enlace (Direccion MAC), gestionar
la deteccion o correccion de errores, y ocuparse del control de flujo entre equipos
(para evitar que un equipo mas rapido desborde a uno mas lento). Mientras que
en la capa de red se habla de paquetes y direccion IP, en esta capa se habla
de tramas y direcciones MAC. Las tramas simplemente representan otra forma
de segmentar la informacion de los paquetes, y las direcciones MAC permiten
reconocer un dispositivo ya no de manera logica sino fsica. En otras palabras,
cada dispositivo fsico posee una unica direccion MAC, aunque su IP pueda variar

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


242

a lo largo del tiempo.


Dadas estas situaciones cabe recalcar que el dispositivo que usa la capa de
enlace es el Switch que se encarga de recibir los datos del router y enviar ca-
da uno de estos a sus respectivos destinatarios. Para esto simplemente posee
una tabla en la que aparea direcciones IP con direcciones MAC con el fin de po-
der encaminar la informacion al dispositivo de destino. Ademas se encarga de
la correccion de errores, dado que la informacion cuando viaja por medios fsi-
cos puede sufrir alteraciones debidas, por ejemplo, a una interferencia. De esta
manera se verifica la integridad de la informacion.
La capa fsica por su parte es la que se encarga de las conexiones globales
de la computadora hacia la red, tanto en lo que se refiere al medio fsico como
a la forma en la que se transmite la informacion. Sus principales funciones se
pueden resumir como:

Definir el medio o medios fsicos por los que va a viajar la comunicacion,


como tipos de los cables (coaxial o fibra optica), o si la informacion viaja por
el aire (en caso de ser una red WiFi).

Definir las caractersticas materiales (componentes y conectores mecani-


cos) y electricas (niveles de tension) que se van a usar en la transmision de
los datos por los medios fsicos.

Definir las caractersticas funcionales de la interfaz (establecimiento, man-


tenimiento y liberacion del enlace fsico).

Manejar las senales electricas del medio de transmision, polos en un en-


chufe, etcetera.

Garantizar la conexion (aunque no la fiabilidad de dicha conexion).

Como podemos observar es la capa mas concreta de todas, dado que se encarga
de los medios fsicos propiamente dichos.

Para Reflexionar

Contrastar la capa de aplicacion con la capa fsica y observar el gran


salto de abstraccion que existe entre una y otra capa.

Actividad 9

Analizar una red hogarena o de una organizacion y como cada capa


forma parte de la red.

8.4. Introduccion al HTML


Hasta el momento hemos visto diversos lenguajes de programacion como G OBS -
TONES y P YTHON ; pero existen lenguajes para fines especficos, lenguajes tam-
bien utilizados en informatica, que no entran en la categora de lenguaje de pro-
gramacion. Uno de estos lenguajes informaticos es el denominado HTML, de
las siglas en ingles HyperText Markup Language. Este lenguaje es utilizado pa-
ra describir paginas web. No posee elementos como repeticion, mecanismo de
pasaje de parametros ni alternativas condicionales. En cambio, solo permite des-
cribir en forma estatica que contenido poseera una pagina web. Por esta razon

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


243

entra en el grupo de los denominados lenguajes de marcado, es decir, lenguajes


puramente descriptores de contenidos.
El lenguaje HTML se basa en la idea de tags. Existen tags para describir
imagenes, parrafos de texto, links, tablas, ttulos, y en general, la mayora del Tambien conocidas en espanol co-
contenido que haya visto en paginas web. Todos los tags poseen la siguiente for- mo marcas.
ma: <tag>contenido del tag</tag>. Entonces, puede observarse que cuando
empezamos a describir un tag lo haremos con <tag>, y cuando queremos cerrar
ese mismo tag lo haremos con </tag>. Por ejemplo, para describir un parra-
fo utilizaremos el tag <p>, de la siguiente manera: <p>Esto es un parrafo de
texto.</p>. Dentro la apertura y cierre de un determinado tag podemos incluir
contenido, dependiendo de que tag se trate, dado que no todos los tags poseen
contenido. El de parrafo generalmente s, pero como veremos mas adelante, el
tag que describe una imagen usualmente no tiene contenido.

Lectura Obligatoria

Para conocer los distintos tags que se pueden utilizar en la descripcion


de una pagina web puede consultar

http://es.wikipedia.org/wiki/HTML

Por otra parte, cada tag a su vez puede contener atributos. Los atributos son ca-
ractersticas diferentes que puede tener cada tag. Por ejemplo, el tag de image-
nes posee como atributo la URL de la imagen a mostrar, lo cual se escribe como
<img src="./imagenes/mifoto.jpg/>.
Por ultimo, si bien HTML provee tags que permiten describir cuestiones de
estilo y estetica de las paginas, por ejemplo estilo de la fuente de un texto, se
elige no utilizar estos tags dado que existe otro lenguaje que permite describir
solo el estilo de las paginas HTML. Este otro lenguaje es CSS, de las siglas en
ingles Cascading Style Sheets. Dado el alcance de esta carpeta no ahondaremos
demasiado en la estetica de las paginas.

Para Ampliar

Si desea aprender a brindar estetica a las paginas puede consultar

www.w3schools.com/css/

Para Reflexionar

En apartados anteriores hemos mencionado la idea de separacion de


incumbencias. Como cree que esta idea se relaciona con la eleccion
de poseer HTML y CSS y no simplemente un lenguaje que agrupe a
ambos?

En relacion con las redes de computadoras, estos dos lenguajes de marcado se


encontraran en la capa de aplicacion del modelo OSI. De hecho, el protocolo
encargado de transmitir los textos escritos en estos dos lenguajes es el HTTP.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


244

8.4.1. Descripcion basica de una pagina web


Las paginas web a nivel global se dividen en dos grandes secciones. Una se co-
noce como encabezado, delimitado por el tag <head>, que es la parte donde se
describe la metainformacion de la pagina, es decir, informacion que no esta pen-
sada para ser vista por el usuario, pero que es utilizada por los navegadores o
programas que interpretan el HTML con diversos fines. Por ejemplo, el estilo CSS
que se aplicara a una pagina suele incluirse en la misma seccion de la pagina.
Luego del encabezado viene el cuerpo, definido por el tag <body>, que repre-
senta el contenido a mostrar de la pagina. A modo de ilustracion, presentamos la
siguiente pagina:

<head>
<style type="text/css">
body {background-color:yellow}
</style>
</head>
<body>
<h1>Biografa de Miguel de Cervantes</h1>
<p>
Consulte:
<a href="http://es.wikipedia.org/wiki/Miguel_de_Cervantes">
Cervantes
</a>
</p>
</body>

Podemos analizar varios elementos de esta descripcion. Sobre cuestiones de es-


tilo que ya hemos visto en lenguajes de programacion, puede notar que el codigo
se indenta para obtener mayor legibilidad. Sobre anidamiento de elementos (co-
mo cuando anidabamos alternativas condicionales), podemos observar que los
tags HTML estan hechos para poder anidarse unos dentro de otros, aunque al-
gunas combinaciones puede carecer de sentido.
Actividad de Programacion 10

Construir una pagina HTML con base en la siguiente descripcion. Para


resolver el ejercicio puede utilizar el procesador de texto plano que mas
guste (Notepad, por ejemplo). Solo debe tener en cuenta que la exten-
sion del archivo a guardar debe ser .html.

Disenar una pagina que posea los siguientes elementos en orden:


1. El ttulo de la pagina sera Los lenguajes de programacion.
2. Primer parrafo:
En esta pagina intentamos transmitir rapidamente la necesidad
de aprender a programar sin darle gran relevancia al lenguaje
particular que aprendamos, sino a las ideas que lo conforman.
Para ello mostramos la vastedad de la variedad de lenguajes de
programacion a traves de un grafico de tipo galaxia, generado a
partir de los vnculos que se establecen actualmente entre ellos,
segun las conexiones que aparecen en Wikipedia (se supone que
dos lenguaje estan conectados si Wikipedia cita a uno de ellos
mientras habla del otro).

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


245

3. Imagen que apunte a la URL http://i.imgur.com/DFPgr.png


4. Segundo parrafo:
Cada estrella representa un lenguaje, y se conecta con otras con
las que tiene vnculos (como dijimos, segun Wikipedia). El tamano
de cada estrella se determina por el numero de conexiones que
tiene. As, las estrellas; mas grandes estan formadas por aquellos
lenguajes conectados a muchos otros.
5. Tercer parrafo:

Los colores intentan agrupar a los lenguajes segun sus carac-


tersticas, y muestran la extension de los diferentes paradigmas
de programacion (un paradigma de programacion es un conjunto
de ideas y conceptos vinculados a la forma en que se relacio-
nan las nociones necesarias para solucionar problemas usando
un lenguaje de programacion) y de los grupos dentro de estos
paradigmas.
6. Cuarto parrafo:
Uno podra sentirse perdido en semejante galaxia y pensar que
el lenguaje en el que trabaja, o el que aprende, es insignificante;
pero recordemos que nuestro sol es apenas un punto en la ga-
laxia, y esta apenas una de cientos de miles... y no por eso nos
restamos importancia o dejamos de hacer lo que debemos y de
vivir nuestra vida. Observemos este vdeo donde uno puede lle-
gar a hacerse la idea del tamano de nuestro planeta o sistema
solar...

7. Finaliza con el siguiente codigo

<div>
<div style="text-align:center;"><embed
height="315" width="560"
type="application/x-shockwave-flash"
src="http://www.youtube.com/v/HEheh1BH34Q?version=3&hl=es_ES&rel=0"
allowfullscreen="true"
allowscriptaccess="always" /><p></p></div>
</div>

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


246

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


247

Aplicaciones

En esta ultima unidad mencionaremos dos de las principales formas con las que
se implementa la ejecucion de programas para un lenguaje de programacion: in-
troduciremos la idea de IDE, herramienta que usan los programadores para pro-
gramar a escala industrial, y realizaremos un ultimo programa final, con el fin de
integrar la mayora de los conocimientos adquiridos en las unidades anteriores.

9.1. Interpretes y compiladores


En unidades anteriores no analizamos demasiado las caractersticas de los len-
guajes que utilizamos. En este apartado nos interesara discutir sobre dos tipos de
implementaciones para lenguajes de programacion, que los separan en lengua-
jes interpretados y lenguajes compilados. Cualquier lenguaje puede ser compila-
do o ser interpretado, por lo que esta designacion solo observa de que manera
se implementa su forma de ejecucion y no a alguna caracterstica subyacente A ciertos lenguajes interpretados
del propio lenguaje. Esta categorizacion basica es algo que los programadores tambien se les conoce como len-
guajes de scripting.
usualmente deben conocer, dado que la forma con la que se trabaja con uno y
otro tipo de lenguaje no es exactamente la misma.
Definicion 9.1.1. Un lenguaje de programacion interpretado es aquel en el que
los programas codificados son interpretados por un programa interprete que lo
ejecuta indirectamente.

Definicion 9.1.2. Un lenguaje de programacion compilado es aquel en el que


sus programas son dados a un programa compilador, que convierte el progra-
ma fuente a codigo maquina, el que luego es ejecutado por una computadora
determinada con ciertas caractersticas.

En nuestro caso, tanto G OBSTONES como P YTHON, pertenecen a la familia de


lenguajes interpretados, dado que para ambos existe un interprete que ejecuta
los programas resultantes en esos lenguajes. Es teoricamente posible escribir
un compilador o un interprete para cualquier lenguaje, sin embargo en algunos
lenguajes una u otra implementacion es mas sencilla porque se disenaron con
una implementacion particular en mente. Es decir, podra existir un compilador
para G OBSTONES o para P YTHON, y aun as seguiran siendo exactamente los
mismos lenguajes con las mismas caractersticas que los definen, excepto en la
forma en que se los ejecuta.
Por su parte, para los lenguajes compilados, una vez escrito el programa, este
se traduce a partir de su codigo fuente por medio de un compilador en codigo eje-
cutable para una determinada plataforma (combinacion de hardware especfico

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


248

y sistema operativo subyacente). Algunos ejemplos tpicos de lenguajes compi-


lados son C, C++, Pascal, Algol, etcetera.
Actividad 1

Buscar por la web al menos 3 lenguajes mas que sean interpretados y 3


lenguajes mas que sean compilados.

Existen ventajas y desventajas para los lenguajes interpretados. Como principal


ventaja podemos decir que generalmente son multiplataforma, es decir, un mis-
Lo que se adapta a cada sistema es mo programa no es dependiente del hardware en donde se ejecuta. Ademas,
el interprete, pero no los programas el tamano que ocupan los programas resultantes suelen ser menores dado que
que escribimos con el lenguaje. Es-
to facilita la tarea del programador
contienen menos informacion relativa a la ejecucion en una maquina particular.
dado que debe preocuparse menos Pero como principal desventaja podemos encontrar que la velocidad con la que
por las caractersticas especficas se ejecutan los programas interpretados es muchsimo mas lenta (en un orden
del hardware subyacente sobre el de 10 veces mas lento) que en lenguajes compilados. Esto es as porque los len-
que correran los programas.
guajes compilados pueden optimizarse segun las caractersticas de la plataforma
donde compilan. Los lenguajes interpretados por el contrario, al ser independien-
tes de la plataforma, es mas difcil que aprovechen todos los beneficios de la
plataforma subyacente en la que corren. Sin embargo, muchos lenguajes inter-
pretados, como P YTHON, si bien son interpretados, compilan ciertas partes de
sus programas para que su eficiencia en ejecucion se vea mejorada.

9.2. IDEs
A medida que los programas se hacen cada vez mas grandes se vuelve poco
viable codificarlos en un simple editor de textos. Por esta razon surgieron los
entornos de desarrollo integrados, mas comunmente conocidos como IDEs, por
sus siglas en ingles.
Integrated Develpment Environ- Estas herramientas suelen estar compuestas de distintos elementos, entre las
ments. que podemos mencionar:

Un editor de texto.

Un compilador o interprete.

Un depurador de codigo (debugger ).

Un sistema de organizacion en proyectos.

Un sistema de control de versiones.

A veces, ayuda para la construccion de interfaces graficas de usuario.

Los editores de texto que suelen venir incorporados en los IDEs ayudan enorme-
mente a la tarea del programador. Suelen tener iluminacion de la sintaxis, auto-
completado de palabras segun el lenguaje en el que se codifica, e informacion
adicional sobre procedimientos, funciones, tipos y objetos codificados. Proveen
un marco para agilizar y facilitar la tarea del programador de mantener y codificar
programas, y ocuparse de detalles importantes mientras que el editor se encar-
ga de rellenar los que son mas mecanicos. A estos editores se anaden formas
comodas de correr los programas, trayendo consigo generalmente un interprete
para correrlos o una forma de comunicacion con el compilador del lenguaje en el
que se este codificando.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


249

G.9.1. Eclipse y P YTHON

Para analizar pedazos de programas con el fin de inspeccionar errores en la


ejecucion de los mismos, los IDEs suelen traer como herramienta lo que se co-
noce como debugger (o en castellano, depurador ). Un debugger es un programa
que ejecuta paso a paso el programa que queramos analizar, y nos permite de-
tenernos en distintos puntos de la ejecucion del mismo para poder observar los
valores y efectos que va generando el programa. Es una herramienta poderosa
pero al mismo tiempo limitante en algunos casos, dado que nos obliga a pen-
sar operacionalmente a los programas. Debe usarse con debida discresion y por
eso para el contexto de esta carpeta no alentamos el uso de esta herramienta,
aunque a escalas industriales es de gran ayuda.
Los sistemas de control de versiones son algo ajeno a los lenguajes de pro-
gramacion. Manejan los cambios que realizamos sobre distintos archivos, pudien-
do volver a versiones anteriores y llevando un registro de cada cambio efectuado.
Son muy utiles para los trabajos realizados entre equipos numerosos de progra-
madores, dado que de esta manera se pueden gestionar de forma organizada
los cambios que realiza cada programador al programa en el que se encuentre
trabajando el equipo.
Por ultimo, las interfaces graficas en muchas ocasiones son codificadas de
manera grafica, y no textual como sucede con el resto del programa. En esta
carpeta no trabajamos demasiado con interfaces graficas, aunque trabajamos un
poco con P YGAME, que nos permite graficar en pantalla de distintas formas. Una
herramienta adicional que podra proveer un IDE en este sentido podra ser un
editor de graficos que produzca codigo para esta biblioteca.
Algunos IDEs son compatibles con multiples lenguajes de programacion, co-
mo es el caso de Eclipse, disenado originalmente para el lenguaje Java. En este
IDE puede incorporarse la funcionalidad para lenguajes alternativos mediante el
uso de plugins. Esto significa que el IDE es ampliable por programadores que
deseen disenar nuevas herramientas y funcionalidades. Eclipse tiene plugins pa- Modulos adicionales a un programa
ra C, C++, Ada, Perl, Python, Ruby y PHP, entre otros. Tambien posee plugins base, que pueden ser agregados
durante la ejecucion del programa,
para diseno de programas web, juegos, etc. En el grafico G.9.1 puede verse el a traves de alguna forma de confi-
entorno Eclipse con el plugin Pydev, utilizado para programar en P YTHON en este guracion.
IDE.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


250

Actividad 2

Investigar 2 IDEs mas (no importa el lenguaje de programacion con el


que operen) y enumerar las caractersticas que poseen. No es nece-
sario descargarlos. Esta informacion podra extraerse de sus paginas
oficiales.

9.3. Ejercicio integrador


Para finalizar esta carpeta realizaremos un ejercicio que incluye la mayora de
los conceptos vistos hasta el momento. La intencion es desarrollar un sistema
llamado QMDB, que administra pelculas, actores, directores y series.
Un version inspirada en la base de De cada tem se sabe lo siguiente:
datos sobre pelculas y series lla-
mada IMDB. De las pelculas y series se sabe su nombre, su director, el elenco de acto-
res que participo y el ano de lanzamiento. De las pelculas particularmente
se conoce su recaudacion total en los cines (en millones de dolares) y de
http://www.imdb.com/ las series la cantidad de temporadas que posee.

De los actores y directores se sabe su nombre y edad. De los actores se


sabe la cantidad de premios que gano y de los directores una lista con
los estilos de pelculas que dirigieron. Los estilos a asignar son drama,
accion, ciencia ficcion y comedia.

Actividad de Programacion 3

Codifique en objetos el sistema descrito en el enunciado.

9.3.1. Codificacion del modelo


Es importante notar que dado un actor o director no es posible obtener de mane-
ra directa en que pelculas y series trabajo, sino que se debe recorrer el total de
pelculas y series y encontrar aquellas en los que dicho actor o director participo.
Tambien es importante notar que entre pelculas y series, y entre actores y di-
rectores, hay atributos compartidos. Se debe tener en cuenta esto al modelar los
objetos del sistema. Ademas los actores no pueden ser directores y vicerversa.
De esta manera se simplifica el sistema, dado que muchas de estas cuestiones
seran mas complejas de modelar.
Actividad de Programacion 4

Codificar el siguiente mensaje polimorfico que deben poder responder


los objetos del sistema.

Ejercicio 9.3.1. Implementar para pelculas, series, actores y directores el men-


saje mostrarse, que imprime de forma adecuada el tipo de objeto junto con su
nombre. Notar que todos estos objetos poseen un nombre. Teniendo este codigo
de ejemplo:

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


251

if __name__ == __main__:
leonardoDiCaprio = Actor("Leonardo Di Caprio", 37, 3)
kateWinslet = Actor("Kate Winslet", 37, 1)
jamesCameron = Director("James Cameron", 58,
["drama", "ciencia ficcion"])
unaPeli = Pelicula("Titanic", jamesCameron,
[leonardoDiCaprio, kateWinslet],
1997, 187000)
Impresor().mostrar([unaPeli,
jamesCameron,
kateWinslet,
leonardoDiCaprio])
se debera mostrar como resultado:
Pelicula: Titanic
Director: James Cameron
Actor: Kate Winslet
Actor: Leonardo Di Caprio

9.3.2. Base de datos y consultas


El proposito de este sistema sera almacenar la informacion provista por el mo-
delo codificado en el apartado anterior, pudiendo agregar, eliminar o modificar
datos. Este tipo de aplicaciones se conoce con el nombre de ABM, que significa
Altas-Bajas-Modificaciones, ya que poseen como funcion especfica justamente
el poder realizar estas tres operaciones, posibilitando tambien formas de poder
extraer informacion del sistema.
Para poder persistir los datos usaremos un pequeno motor de base de datos
que viene integrado con P YTHON, llamado SQLite. Es un motor no tan completo
e importante como MySQL, pero nos permitira poder codificar este sistema sin
ningun problema.

Introduccion a SQLite en P YTHON


La programacion con SQLite en P YTHON es muy simple. Primero debemos im-
portar la biblioteca que provee los procedimientos necesarios para utilizar esta
base de datos. Esto se hace con la lnea: Llamamos as a un modulo predefi-
nido que puede agregarse a nues-
import sqlite3 tro programa. En ingles se deno-
mina library, lo cual muchas veces
La forma de obtener acceso a una base de datos es con el procedimiento lleva a que en castellano se utilice
connect, que sera utilizado, por razones de simplicidad, exactamente de esta la incorrecta denominacion de li-
brera.
forma:
import sqlite3

if __name__ == __main__:
conn = sqlite3.connect(":memory:", isolation_level=None)
Este procedimiento nos retornara una conexion a la base de datos, que de-
beremos asignar a una variable para utilizar de forma posterior, tal como sucede
en el ejemplo anterior.
La conexion por s sola no nos sirve de mucho. A cada conexion puede pedir-
se un objeto de tipo cursor que nos permitira realizar consultas sql mediante el
procedimiento execute, que recibe por parameto la consulta sql a ejecutar.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


252

Actividad de Programacion 5

Ejecutar el siguiente ejemplo y observar los resultados del programa.

El siguiente ejemplo muestra como podemos crear una tabla, como insertar una
fila y como realizar una consulta a la tabla creada:

import sqlite3

if __name__ == __main__:

conn = sqlite3.connect(":memory:")

c = conn.cursor()

# Creo una tabla persona


c.execute("CREATE TABLE Persona
(nombre text, apellido text)")

# Inserto una persona en la tabla Persona


c.execute("INSERT INTO Persona VALUES (Pepe,Argento)")

# Selecciono todas las personas que tienen nombre "Pepe"


t = (Pepe,)
c.execute("SELECT * FROM Persona WHERE nombre=?", t)
print c.fetchone()

Podemos observar que con el mensaje fetchone pedimos un dato de los tantos
que podra traer la consulta. Para obternerlos todos en forma de lista podemos
utilizar el mensaje fetchmany.
Lectura Obligatoria

Todo lo que es posible hacer con la librera SQLite lo podemos encontrar


en el siguiente enlace.

http://docs.python.org/library/sqlite3.html

Actividad de Programacion 6

Resolver los siguientes ejercicios con el fin de modelar las tablas y el


alta de elementos del sistema.

Las tablas del sistema son las siguientes:

Actor, con columnas nombre (primary key), edad y cantidad de premios.

Director, con columnas nombre (primary key) y edad.

EstiloDeDirectores, con columnas nombre de director (foreign key) y nom-


bre de estilo.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


253

Pelcula, con columnas nombre, nombre de director (foreign key), fecha y


recaudacion.

Serie, con columnas nombre, nombre de director (foreign key), fecha y can-
tidad de temporadas.

ElencoDePeliculas, con columnas nombre de actor (foreign key) y nombre


de pelcula (foreign key).

ElencoDeSeries, con columnas nombre de actor (foreign key) y nombre de


serie (foreign key).

Ejercicio 9.3.2. Escribir un procedicimiento llamado crearTablasDelSistema que


genere todas las tablas descritas anteriormente.
Nota: dividir en subtareas.

Ejercicio 9.3.3. Agregar un mensaje polimorfico transformarEnFila a los obje-


tos Actor, Pelcula, Serie y Director, que convierta las propiedades basicas (las
que no son ni de elenco de obras ni de estilos de directores) en una tupla con
el mismo orden que las columnas de las respectivas tablas de dichos objetos.
Para las propiedades de elenco y estilos, agregar dos mensajes mas llamados
transformarEnFilaElenco y transformarEnFilaEstilo, que retornen en una
lista de tuplas con nombre de la obra y nombre de actor, y nombre de director y
nombre del estilo respectivamente.

Como ayuda, puede utilizar el hecho de que estos metodos seran utilizados como
en el siguiente ejemplo:

def insertarTitanic(cursor):
leonardoDiCaprio = Actor("Leonardo Di Caprio", 37, 3)
kateWinslet = Actor("Kate Winslet", 37, 1)
jamesCameron = Director("James Cameron", 58,
["drama", "ciencia ficcion"])
titanic = Pelicula("Titanic", jamesCameron,
[leonardoDiCaprio, kateWinslet],
1997, 187000)

cursor.execute(INSERT INTO Actor VALUES (?,?,?),


leonardoDiCaprio.transformarEnFila())
cursor.execute(INSERT INTO Actor VALUES (?,?,?),
kateWinslet.transformarEnFila())
cursor.execute(INSERT INTO Director VALUES (?,?),
jamesCameron.transformarEnFila())
cursor.executemany(INSERT INTO EstilosDeDirector VALUES (?,?),
jamesCameron.FilasEstilo())

cursor.execute(INSERT INTO Pelicula VALUES (?,?,?,?),


titanic.transformarEnFila())
cursor.executemany(INSERT INTO ElencoDePelicula VALUES (?,?),
titanic.FilasElenco())

Ejercicio 9.3.4. Definir los siguientes procedimientos:

transformarEnActor, que recibe una tupla con el contenido basico de un


actor y retorna un objeto actor con dichos atributos.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


254

transformarEnDirector, que recibe una tupla con el contenido basico de


un director y una lista de tuplas provenientes de la tabla de estilos y retorna
un objeto director con dichos atributos.
transformarEnPelicula, que recibe una tupla con los atributos de una
pelcula y una lista de tuplas de la tabla de elenco de pelculas, y retorna
un objeto pelcula con dichos atributos.
transformarEnSerie, que recibe una tupla con los atributos de una serie y
una lista de tuplas de la tabla de elenco de series, y retorna un objeto serie
con dichos atributos.
Nota: utilizar una subtarea llamada transformarEnElenco para los dos ultimos
procedimientos que reciba la lista de tuplas de actores y series o pelculas y
retorne una lista de actores, es decir, al elenco de dichas obras. Esto facilitara la
codificacion de estos procedimientos.

Tambien puede tener en cuenta que en P YTHON es posible asignar una tupla
a una tupla de variables como suceda en G OBSTONES. En otras palabras, es
posible escribir algo como:
(nombre, edad, cantidadDePremios) = ("Robert De Niro", 69, 51)
Ejercicio 9.3.5. Utilizando lo definido en ejercicios anteriores definir el procedi-
miento habitarBaseDeDatos que reciba por parametro un cursor a una base de
datos e inserte informacion en la misma. Debe agregar a la base al menos 3
pelculas y 2 series de su preferencia, cada una con al menos 2 actores.

Ejercicio 9.3.6. Definir procedimientos para insertar cada tipo de elemento del
sistema a las tablas correspondientes.

9.3.3. Consultas a la base de datos


Actividad de Programacion 7

Resolver las siguientes consultas SQL.

Habiendo definido la forma con la que transformaremos objetos a filas de tablas


y filas de tablas a objetos, procederemos a escribir en el lenguaje SQL diversas
consultas que nos permitiran obtener informacion de la base de datos. Los resul-
tados de las consultas deberan ser convertidos a objetos. Para probar cada uno
de los siguientes ejercicios mantenga el siguiente esquema de procedimiento
principal:
if __name__ == __main__:
conn = sqlite3.connect(:memory:)
cursor = conn.cursor()
crearTablasDelSistema(cursor)
habitarBaseDeDatos(cursor)
#Probar desde este punto los procedimientos pedidos.
# (complete con su propio codigo)
Ejercicio 9.3.7. Definir procedimientos todosLosDirectores, todasLasPeliculas
y todasLasSeries, que dado un cursor ejecuten una consulta que obtenga para
cada caso todos los objetos de cada tipo correspondiente.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


255

Nota: para el caso de pelculas, series y directores tener en cuenta que para
cada fila deberemos obtener de las tablas de elencos y estilos las filas corres-
pondientes a cada uno de estos objetos.
Recuerde utilizar los procedimientos de transformacion de tuplas en objetos
definidos anteriormente.

Tenga en cuenta que el resultado de una consulta puede ser tomado como se-
cuencia a iterar. Para ilustrar esto le proveemos ya codificado el procedimiento
todosLosActores, para que observe una posible forma de resolver los procedi-
mientos pedidos.
def todosLosActores(cursor):
resultList = []
for fila_actor in cursor.execute(SELECT * FROM Actor):
newActor = transformarEnActor(fila_actor)
resultList.append(newActor)
return resultList
Ejercicio 9.3.8. Definir el procedimiento mostrarTodaLaBase que utilizando los
anteriores procedimientos y el mensaje mostrarse de cada objeto del sistema,
muestra todos los objetos existenes en el sistema.

Ejercicio 9.3.9. Definir el procedimiento hayMasPeliculasQueSeries que retor-


na verdadero si en el sistema existen mas pelculas que series y falso en caso
contrario.

Ejercicio 9.3.10. Definir el procedimiento cantidadDeDirectoresDeCF que re-


torna la cantidad de directores de Ciencia Ficcion existentes en el sistema.

Ejercicio 9.3.11. Definir el procedimiento elActorMasViejo que retorna el actor


mas viejo en el sistema.

Ejercicio 9.3.12. Definir el procedimiento directorConMasPeliculas que retor-


na el director que filmo mas pelculas en el sistema.

Ejercicio 9.3.13. Definir el procedimiento serieConMasTemporadas que retorna


la serie que posee mas temporadas en el sistema.

Ejercicio 9.3.14. Definir el procedimiento recaudoMasDe que dado una suma de


dinero y un nombre de pelcula retorna verdadero si la pelcula recaudo mas que
la suma dada por parametro.

Ejercicio 9.3.15. Definir el procedimiento directoresQueFilmaronMasDe que da-


da una cantidad de pelculas retorna una lista de directores que filmaron mas de
dicha cantidad de pelculas.

Ejercicio 9.3.16. Definir el procedimiento cantidadTotalDePremios que retorna


la cantidad total de premios recibidos por actores.

Ejercicio 9.3.17. Definir el procedimiento directoresConSeriesYPeliculas que


retorna en una lista aquellos directores que filmaron al menos una serie y al me-
nos una pelcula.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


256

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


257

La herramienta P Y G OBSTONES

La herramienta P Y G OBSTONES es un entorno de programacion basico para el


lenguaje G OBSTONES. El programa esta implementado en P YTHON y se compo-
ne de varios modulos que pueden utilizarse para analizar y ejecutar programas
escritos en G OBSTONES.
En este apartado se detallan los pasos necesarios para poder ejecutar la he-
rramienta P Y G OBSTONES. Para esto se requiere instalar primero un interprete de
P YTHON. Se indica como instalar y utilizar el programa con el interprete tradicio-
nal de P YTHON, pero no se descartan implementaciones alternativas.

Instalacion
El primer paso es obtener los scripts que conforman el entorno de programacion
P Y G OBSTONES 0.9.6. Se encuentran en un archivo zip que esta disponible para
descargar desde el sitio de SourceForge. La direccion del sitio es:

http://gobstones.sourceforge.net/

All se debe entrar en la seccion Download Gobstones files, donde se encuen-


tra el archivo PyGobstones-0.9.6.zip El archivo PyGobstones-0.9.6.zip debe

G.2. Descarga de P Y G OBSTONES

descomprimirse en un directorio. All se encontraran varios archivos con exten-


sion .py que conforman la implementacion de P Y G OBSTONES.
Los restantes pasos dependen del sistema operativo que se este utilizando.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


258

Usuarios de Windows
Para los usuarios de Windows, el siguiente paso es conseguir e instalar una
version de P YTHON. El interprete tradicional de P YTHON para Windows se puede
descargar desde:

http://python.org/ftp/python/2.7.3/python-2.7.3.msi

G.3. Descarga de P YTHON

Una vez obtenido el archivo (por ejemplo, python-2.7.2.msi) se lo debe abrir


para proceder con la instalacion. Alcanza con realizar la instalacion con todas
las opciones predeterminadas. Hecho esto, ya se esta en condiciones de ejecu-

G.4. Instalacion de P YTHON

tar P Y G OBSTONES. Para cargar la herramienta debe ejecutarse el interprete de


P YTHON sobre el script Main.py que se encuentra en el directorio de P Y G OBS -
TONES . Esto se puede hacer utilizando el boton derecho sobre el archivo Main.py
y eligiendo la opcion Abrir con, desde donde debe seleccionarse el link al pro-
grama ejecutable C:\Python27\pythonw.exe (o la ruta en la que este instalado).
Alternativamente, en la mayora de las configuraciones de Windows se puede
hacer doble click directamente sobre el archivo Main.py.

Usuarios de GNU/Linux
Las distribuciones de Linux generalmente ya traen el interprete de P YTHON ins-
talado. Ademas de esto, para ejecutar P Y G OBSTONES se requiere instalar el pa-
quete python-tk. Para instalar los paquetes que falten, se deben buscar utili-

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


259

G.5. Abrir la herramienta P Y G OBSTONES

zando el administrador de paquetes (se precisan permisos de administrador para


esto).
Una vez hecho esto, se debe abrir una terminal, ubicarse en el directorio de
P Y G OBSTONES y tipear el comando: python Main.pyw.

Uso
La interfaz de P Y G OBSTONES es similar a la de un editor de textos comun y
corriente. El editor permite crear y modificar programas de G OBSTONES, que se
guardan en archivos de texto con extension .gbs.
La funcionalidad provista por la herramienta es mnima. Una vez escrito el
programa, la opcion de menu Gobstones Ejecutar permite ejecutarlo (lo cual
se puede hacer mas comodamente con la tecla F5). Una vez que termino de

G.6. Usar P Y G OBSTONES

ejecutar el programa (si es que no tiene errores), la herramienta abre un Visor de


Tableros que permite mirar:
Tablero Inicial: el estado del tablero antes de ejecutar el programa.
Tablero Final: el estado del tablero despues de haber ejecutado el programa.
En general, P Y G OBSTONES inicia el programa sobre un tablero aleatorio. Des-
de el Visor de Tableros tambien se puede modificar el Tablero Inicial para que
la herramienta inicie el programa sobre el tablero indicado. Se utiliza el mouse
para, con el boton izquierdo agregar bolitas, y con el boton derecho quitar bolitas
de alguna celda. Con las flechas de direccion puede moverse la celda actual.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


260

Ademas, el menu Tablero permite abrir y guardar tableros en archivos con ex-
tension .gbb.

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


261

Sokoban en P YTHON

En este apendice presentamos el codigo fuente en P YTHON de los modulos ne-


cesarios para definir la aplicacion Sokoban presentado como ejercicio integrador
en la unidad 5. Para cada modulo presentamos un apartado cuyo ttulo es el
nombre del archivo, y cuyo contenido es el texto que debe ir en dicho archivo
para definir al modulo correspondiente.

Main.py
from Common import quitGame
from Constants import SCREEN_WIDTH, SCREEN_HEIGHT, BOX
from Game.SokobanLogic import playerMove
from Level import newLevel
from Resources import loadResources
from SokobanDrawing import drawAllObjects, drawWinTitle
from SokobanLogic import winGame
import pygame

def paint(screen, resources, coordMap, win):


screen.fill((0,0,0))
drawAllObjects(screen, resources, coordMap)
if win:
drawWinTitle(screen)
pygame.display.flip()

def main():
pygame.mixer.pre_init(44100, -16, 2, 512)
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH(), SCREEN_HEIGHT()))
pygame.display.set_caption("Sokoban")
clock = pygame.time.Clock()
resources = loadResources()
coordMap = newLevel(1)

win = False

while True:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
quitGame()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
quitGame()
elif event.key == pygame.K_1:
coordMap = newLevel(1)
elif event.key == pygame.K_2:
coordMap = newLevel(2)
else:
playerMove(coordMap, event.key, win)

win = winGame(coordMap[BOX()])
paint(screen, resources, coordMap, win)

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


262

if __name__ == __main__:
main()

Common.py
import pygame
import sys

def quitGame():
pygame.quit()
sys.exit()

def quitGameWithError():
pygame.quit()
sys.exit(1)

Constants.py
#===============================================================================
# CONSTANTS
#===============================================================================

def SCREEN_WIDTH():
return 256

def SCREEN_HEIGHT():
return 288

def WALL():
return wall

def BOX():
return box

def DARKBOX():
return darkbox

def GOAL():
return goal

def PLAYER():
return player

def EMPTY():
return empty

def RES_SIZE_X():
return 32

def RES_SIZE_Y():
return 32

def MIN_POS_X():
return 0

def MAX_POS_X():
return 7

def MIN_POS_Y():
return 0

def MAX_POS_Y():
return 8

def DOWN():
return 0

def UP():
return 1

def LEFT():
return 2

def RIGHT():

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


263

return 3

Level.py
from Constants import EMPTY, WALL, GOAL, PLAYER, BOX
from Constants import DARKBOX
from Resources import resourceNames
from SokobanLogic import collideWith

def level1():
return [[W],[W],[W],[W],[W],[E],[E],
[W],[E],[E],[E],[W],[E],[E],
[W],[E],[W],[E,B],[W],[W],[W],
[W],[E],[E,P],[E],[G],[G,B],[W],
[W],[W],[W],[W],[W],[W],[W]
]

def level1Size():
return (7,5)

def level2():
return [[E],[E],[W],[W],[W],[W],[W],[E],
[W],[W],[W],[E],[E],[E],[W],[E],
[W],[G],[E,P],[E,B],[E],[E],[W],[E],
[W],[W],[W],[E],[E,B],[G],[W],[E],
[W],[G],[W],[W],[E,B],[E],[W],[E],
[W],[E],[W],[E],[G],[E],[W],[W],
[W],[E,B],[E],[B,G],[E,B],[E,B],[G],[W],
[W],[E],[E],[E],[G],[E],[E],[W],
[W],[W],[W],[W],[W],[W],[W],[W]
]

def level2Size():
return (8,9)

def parseCode(code):
if code == E:
return EMPTY()
elif code == W:
return WALL()
elif code == G:
return GOAL()
elif code == P:
return PLAYER()
elif code == B:
return BOX()

def initializeCoordMap(coordMap):
for objName in resourceNames():
coordMap[objName] = []
return coordMap

def reAddBoxesToVerifyDarkBoxes(coordMap):
boxes = coordMap[BOX()]
coordMap[BOX()] = []
for box in boxes:
if collideWith(coordMap, GOAL(), box):
coordMap[DARKBOX()].append(box)
else:
coordMap[BOX()].append(box)

def populateCoordMap(coordMap, level, (w,h)):


x = 0
y = 0
for point in level:
for code in point:
coordMap[parseCode(code)].append((x,y))
if x == (w - 1):
y += 1
x = (x + 1) % w
reAddBoxesToVerifyDarkBoxes(coordMap)

def mkCoordMap(level, levelSize):


coordMap = {}
initializeCoordMap(coordMap)
populateCoordMap(coordMap, level, levelSize)

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


264

return coordMap

def newLevel(levelNumber):
if levelNumber == 1:
return mkCoordMap(level1(), level1Size())
elif levelNumber == 2:
return mkCoordMap(level2(), level2Size())

Resources.py
from Common import quitGameWithError
from Constants import EMPTY, WALL, GOAL, BOX, PLAYER, DARKBOX
import os
import pygame

IMG_DIR = "resources/img"
SONIDO_DIR = "resources/snd"

#===============================================================================
# BASIC LOAD RESOURCES
#===============================================================================

#Load some image file


def load_image(nombre, extension="png", alpha=False, folder=IMG_DIR):
# Encontramos la ruta completa de la imagen
ruta = os.path.join(folder, nombre+"."+extension)
try:
image = pygame.image.load(ruta)
except:
print "Error, no se puede cargar la imagen: ", ruta
quitGameWithError()
# Comprobar si la imagen tiene "canal alpha" (como los png)
if alpha:
image = image.convert_alpha()
else:
image = image.convert()
return image

#Load some sound file


def load_sound(nombre, extension="ogg"):
ruta = os.path.join(SONIDO_DIR, nombre+"."+extension)
# Intentar cargar el sonido
try:
sonido = pygame.mixer.Sound(ruta)
except pygame.error:
print "No se pudo cargar el sonido:", ruta
sonido = None
return sonido

#Load some music file


def load_music(nombre, extension="ogg"):
ruta = os.path.join(SONIDO_DIR, nombre+"."+extension)
# Intentar cargar el sonido
try:
sonido = pygame.mixer.music.load(ruta)
except pygame.error:
print "No se pudo cargar el sonido:", ruta
sonido = None
return sonido

#===============================================================================
# LOAD RESOURCES
#===============================================================================

#All the resources that must be loaded into the game


def resourceNames():
# Orded by priority drawing, DO NOT CHANGE!!
return [EMPTY(), WALL(), GOAL(), BOX(), PLAYER(), DARKBOX()]

#Load a resource into a dictionary


def loadResource(aDict, resourceName):
aDict[resourceName] = load_image(resourceName)
return aDict

#Creates a dictionary and load all the resources into it


def loadResources():
aDict = {}

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


265

for res in resourceNames():


loadResource(aDict, res)
return aDict

SokobanDrawing.py
from Constants import RES_SIZE_X, RES_SIZE_Y, SCREEN_WIDTH, SCREEN_HEIGHT
from Resources import resourceNames
import pygame

#===============================================================================
# DRAWING OBJECTS
#===============================================================================

def drawObjectInCoord(screen, obj, coord):


(x,y) = coord
screen.blit(obj, (x*RES_SIZE_X(),y*RES_SIZE_Y()))

def drawObjectInCoords(screen, obj, coords):


# completar

def drawAllObjects(screen, resources, coordMap):


# completa

#===============================================================================
# DRAWING TITLES
#===============================================================================

def drawTitle(screen, string, color, pos, fontSize):


font = pygame.font.Font(None, fontSize)
font = font.render(string, True, pygame.Color(color))
screen.blit(font,pos)

def drawTitleWithShadow(screen, string, (x,y), fontSize):


drawTitle(screen,string,"Black",(x-2,y-1), fontSize)
drawTitle(screen,string,"White",(x,y), fontSize)

def drawWinTitle(screen):
drawTitleWithShadow(screen, "YOU WIN!",
(SCREEN_WIDTH()/2 - 56, SCREEN_HEIGHT()/2 - 20), 32)
drawTitleWithShadow(screen, "CHOOSE ANOTHER LEVEL",
(SCREEN_WIDTH()/2 - 110, SCREEN_HEIGHT()/2 + 20), 24)
drawTitleWithShadow(screen, "(PRESS 1 or 2)",
(SCREEN_WIDTH()/2 - 60, SCREEN_HEIGHT()/2 + 40), 24)

SokobanLogic.py
from Constants import WALL, BOX, DARKBOX, DOWN, UP, LEFT, RIGHT, GOAL, \
PLAYER, MAX_POS_Y, MIN_POS_Y, MIN_POS_X, MAX_POS_X
import pygame

#===============================================================================
# COLLISION DETECTION
#===============================================================================

def collideWith(coordMap,objID, coord):


# completar

#===============================================================================
# MAIN LOGIC
#===============================================================================

def updateGame(coordMap,aDir):
oldCoord = coordMap[PLAYER()][0]
newCoord = moveWorker(oldCoord,aDir)
if not collideWith(coordMap, WALL(), newCoord):
if collideWith(coordMap, BOX(), newCoord) or
collideWith(coordMap, DARKBOX(), newCoord):
wasChanged = changeBoxPos(coordMap, aDir, newCoord)
if(wasChanged):
changeWorker(coordMap, newCoord)
else:
changeWorker(coordMap, newCoord)
return coordMap

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


266

def winGame(boxes):
# completar

def playerMove(coordMap, eventKey, win):


if not win:
if eventKey == pygame.K_DOWN:
updateGame(coordMap, DOWN())
elif eventKey == pygame.K_UP:
updateGame(coordMap, UP())
elif eventKey == pygame.K_LEFT:
updateGame(coordMap, LEFT())
elif eventKey == pygame.K_RIGHT:
updateGame(coordMap, RIGHT())

#===============================================================================
# BOXES
#===============================================================================

def canChageBoxPos(coordMap, newCoord):


# completar

def moveBox((x,y),aDir):
if aDir == DOWN():
return (x,y+1)
elif aDir == UP():
return (x,y-1)
elif aDir == LEFT():
return (x-1,y)
elif aDir == RIGHT():
return (x+1,y)

def removeBoxWithType(coordMap, box_type, oldCoord):


x = 0
boxPoses = list(coordMap[box_type])
for boxPos in boxPoses:
if boxPos == oldCoord:
coordMap[box_type].pop(x)
x += 1

def removeOldBoxPos(coordMap, oldCoord):


removeBoxWithType(coordMap, BOX(), oldCoord)
removeBoxWithType(coordMap, DARKBOX(), oldCoord)

def isAGoal(coordMap, boxCoord):


# completar

def addNewBox(coordMap, newBoxCoord):


# completar

def changeBoxPos(coordMap, aDir, oldCoord):


newBoxCoord = moveBox(oldCoord, aDir)
canChange = canChageBoxPos(coordMap, newBoxCoord)
if canChange:
removeOldBoxPos(coordMap, oldCoord)
addNewBox(coordMap, newBoxCoord)
return True
return False

#===============================================================================
# WORKER
#===============================================================================

def changeWorker(coordMap, newCoord):


coordMap[PLAYER()].pop()
coordMap[PLAYER()].append(newCoord)

def moveWorker(oldCoord,aDir):
# completar

def moveWorkerDown((x,y)):
if(y < MAX_POS_Y()):
return (x,y+1)
else:
return (x,y)

def moveWorkerUp((x,y)):
if(y > MIN_POS_Y()):
return (x,y-1)

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


267

else:
return (x,y)

def moveWorkerLeft((x,y)):
if(x > MIN_POS_X()):
return (x-1,y)
else:
return (x,y)

def moveWorkerRight((x,y)):
if(x < MAX_POS_X()):
return (x+1,y)
else:
return (x,y)

TestLevel.py
from Constants import SCREEN_WIDTH, SCREEN_HEIGHT, EMPTY, GOAL, BOX, PLAYER, \
WALL
from Level import parseCode, initializeCoordMap, populateCoordMap, level1, \
level1Size, mkCoordMap, level2, level2Size, newLevel
from Resources import resourceNames
import pygame
import unittest

class Test(unittest.TestCase):

def setUp(self):
pygame.init()
pygame.display.set_mode((SCREEN_WIDTH(), SCREEN_HEIGHT()))

def test_parseCode(self):
self.assertEquals(parseCode(E), EMPTY(), La letra E se debe
corresponder con EMPTY)
self.assertEquals(parseCode(G), GOAL(), La letra G se debe
corresponder con GOAL)
self.assertEquals(parseCode(B), BOX(), La letra B se debe
corresponder con EMPTY)
self.assertEquals(parseCode(P), PLAYER(), La letra P se debe
corresponder con PLAYER)
self.assertEquals(parseCode(W), WALL(), La letra P se debe
corresponder con WALL)

def test_initializeCoordMap(self):
coordMap = {}
coordMap2 = initializeCoordMap(coordMap)

for resourceName in resourceNames():


self.assertTrue(resourceName in coordMap2.keys(), resourceName +
debe ser una key del diccionario)
self.assertEquals(coordMap[resourceName], [], Cada valor del
diccionario debe ser una lista vacia)

def test_mkCoordMap(self):
level = level1()
levelSize = level1Size()

coordMap = {}
initializeCoordMap(coordMap)
populateCoordMap(coordMap, level, levelSize)

coordMap2 = mkCoordMap(level, levelSize)

self.assertEquals(coordMap, coordMap2,
El diccionario debe contener todas las
coordenadas de cada elemento del
nivel a construir
)

def test_newLevel(self):

coordMap1 = {}
initializeCoordMap(coordMap1)
populateCoordMap(coordMap1, level1(), level1Size())

coordMap2 = {}

Introduccion a la Programacion Martnez Lopez y Sawady OConnor


268

initializeCoordMap(coordMap2)
populateCoordMap(coordMap2, level2(), level2Size())

levelMap1 = newLevel(1)
levelMap2 = newLevel(2)

self.assertEquals(coordMap1, levelMap1, El nivel 1 generado no se


corresponde con lo esperado)
self.assertEquals(coordMap2, levelMap2,
El nivel 2 generado no se corresponde con lo
esperado)

if __name__ == "__main__":
unittest.main()

TestResources.py
from Constants import SCREEN_WIDTH, SCREEN_HEIGHT
from Resources import resourceNames, loadResource
from Resources import loadResources
import pygame
import unittest

class Test(unittest.TestCase):

def setUp(self):
pygame.init()
pygame.display.set_mode((SCREEN_WIDTH(), SCREEN_HEIGHT()))

def test_loadResource(self):
oldDict = {}
aDict = loadResource(dict(oldDict), "box")
self.assertTrue(len(oldDict) == len(aDict) - 1,
Se debe agregar exactamente un nuevo elemento al
diccionario)
self.assertTrue("box" in aDict.keys(),
Se debe agregar como nueva clave al diccionario el
resourceName pasado por parametro)

def test_loadResources(self):
aDict = loadResources()
for res in resourceNames():
self.assertTrue(aDict,
"El diccionario debe contener la imagen: " + res)

if __name__ == "__main__":
unittest.main()

Introduccion a la Programacion Martnez Lopez y Sawady OConnor

S-ar putea să vă placă și