|
@@ -1,711 +1,2 @@
|
1
|
|
-[English](#markdown-header-decision-structures-birth-of-a-bird) | [Español](#markdown-header-estructuras-de-decision-nacimiento-de-un-pajaro)
|
2
|
|
-
|
3
|
|
-#Estructuras de decisión - Nacimiento de un Pájaro
|
4
|
|
-
|
5
|
|
-
|
6
|
|
-![main1.png](images/main1.png)
|
7
|
|
-![main2.png](images/main2.png)
|
8
|
|
-![main3.png](images/main3.png)
|
9
|
|
-
|
10
|
|
-
|
11
|
|
-En casi todas las instancias en que queremos resolver un problema hay una o más opciones que dependen de si se cumplen o no ciertas condiciones. Los programas de computadoras se construyen para resolver problemas y, por lo tanto, deben tener una estructura que permita tomar decisiones. En C++ las instrucciones de decisión (o condicionales) se estructuran utilizando `if`, `else`, `else if` o `switch`. Muchas veces el uso de estas estructuras también envuelve el uso de expresiones de relación y operadores lógicos. En la experiencia de laboratorio de hoy practicarás el uso de algunas estructuras de decisión completando el diseño utilizando una clase llamada `Bird`. También repasarás conceptos relacionados a objetos.
|
12
|
|
-
|
13
|
|
-##Objetivos:
|
14
|
|
-
|
15
|
|
-1. Utilizar expresiones relacionales y seleccionar operadores lógicos adecuados para la toma de decisiones.
|
16
|
|
-2. Aplicar estructuras de decisión.
|
17
|
|
-3. Analizar la declaración de una clase para entender cómo crear y manipular objetos de esa clase.
|
18
|
|
-4. Practicar la creación y manipulación de objetos, y la invocación de "setters" y "getters".
|
19
|
|
-
|
20
|
|
-
|
21
|
|
-
|
22
|
|
-##Pre-Lab:
|
23
|
|
-
|
24
|
|
-Antes de llegar al laboratorio debes:
|
25
|
|
-
|
26
|
|
-1. Haber repasado los siguientes conceptos relacionados a estructuras de decisión:
|
27
|
|
-
|
28
|
|
- a. operadores lógicos.
|
29
|
|
- b. `if`, `else`, `else if`.
|
30
|
|
-
|
31
|
|
-2. Haber repasado los siguientes conceptos relacionados a objetos y clases en C++:
|
32
|
|
-
|
33
|
|
- a. creación de objetos de una clase.
|
34
|
|
- b. utilización de métodos "getters" para acceder a los atributos de un objeto.
|
35
|
|
- c. utilización de métodos "setters" para modificar los atributos de un objeto.
|
36
|
|
-
|
37
|
|
-3. Haber estudiado la documentación de la clase `Bird` disponible en [este enlace] (http://ada.uprrp.edu/~ranazario/bird-html/class_bird.html).
|
38
|
|
-
|
39
|
|
-4. Haber estudiado los conceptos e instrucciones para la sesión de laboratorio.
|
40
|
|
-
|
41
|
|
-5. haber tomado el quiz Pre-Lab que se encuentra en Moodle.
|
42
|
|
-
|
43
|
|
-
|
44
|
|
-
|
45
|
|
----
|
46
|
|
-
|
47
|
|
----
|
48
|
|
-
|
49
|
|
-Para facilitar la ejecución de esta experiencia de laboratorio, comenzaremos repasando algunos conceptos relacionados a objetos y describiremos la clase `Bird`.
|
50
|
|
-
|
51
|
|
-------------------------------------------
|
52
|
|
-
|
53
|
|
-##Clases y objetos en C++
|
54
|
|
-
|
55
|
|
-Un *objeto* es un ente que contiene datos y procedimientos para manipularlos. Al igual que cada variable tiene un *tipo* de dato asociada a ella, cada objeto tiene una *clase* asociada que describe las propiedades de los objetos:
|
56
|
|
-sus datos (*atributos*), y los procedimientos con los que se pueden manipular los datos (*métodos*).
|
57
|
|
-
|
58
|
|
-Para definir y utilizar un objeto no hay que saber todos los detalles de los métodos del objeto pero hay que saber cómo crearlo, y cómo interactuar con él. La información necesaria está disponible en la documentación de la clase. Antes de crear objetos de cualquier clase debemos familiarizarnos con su documentación. La documentación nos indica, entre otras cosas, que ente se está tratando de representar con la clase, y cuáles son los interfaces o métodos disponibles para manipular los objetos de la clase.
|
59
|
|
-
|
60
|
|
-Dale un vistazo a la documentación de la clase `Bird` que se encuentra en http://ada.uprrp.edu/~ranazario/bird-html/class_bird.html.
|
61
|
|
-
|
62
|
|
-###Clases
|
63
|
|
-
|
64
|
|
-Una clase es un pedazo de código en donde se describe cómo serán los objetos. La declaración de una clase establece los atributos que tendrá cada objeto de esa clase y los métodos que puede invocar.
|
65
|
|
-
|
66
|
|
-
|
67
|
|
-Si no se especifica lo contrario, los atributos y métodos definidos en una clase serán "privados". Esto quiere decir que esas variables solo se pueden acceder y cambiar por los métodos de la clase (*constructores*, *"setters"* y *"getters"*, entre otros).
|
68
|
|
-
|
69
|
|
-Lo siguiente es el esqueleto de la declaración de una clase:
|
70
|
|
-
|
71
|
|
----
|
72
|
|
-
|
73
|
|
-```
|
74
|
|
- class NombreClase
|
75
|
|
- {
|
76
|
|
- // Declaraciones
|
77
|
|
-
|
78
|
|
- private:
|
79
|
|
- // Declaraciones de variables o atributos y
|
80
|
|
- // prototipos de métodos
|
81
|
|
- // que sean privados para esta clase
|
82
|
|
-
|
83
|
|
- tipo varPrivada;
|
84
|
|
- tipo nombreMetodoPrivado(tipo de los parámetros);
|
85
|
|
-
|
86
|
|
- public:
|
87
|
|
- // Declaraciones de atributos y
|
88
|
|
- // prototipos de métodos
|
89
|
|
- // que sean públicos para todo el programa
|
90
|
|
-
|
91
|
|
- tipo varPública;
|
92
|
|
- tipo nombreMetodoPúblico(tipo de los parámetros);
|
93
|
|
- };
|
94
|
|
-```
|
95
|
|
----
|
96
|
|
-
|
97
|
|
-Puedes ver la declaración de la clase `Bird` en el archivo `bird.h` incluido en el programado de esta experiencia de laboratorio.
|
98
|
|
-
|
99
|
|
-###Objetos
|
100
|
|
-
|
101
|
|
-Un objeto es un ente que contiene datos (al igual que una variable), llamados sus `atributos`, y también contiene procedimientos, llamados `métodos`, que se usan para manipularlos. Los objetos son "instancias" de una clase que se crean de manera similar a como se definen las variables:
|
102
|
|
-
|
103
|
|
-`NombreClase nombreObjeto;`
|
104
|
|
-
|
105
|
|
-Una vez creamos un objeto, podemos interaccionar con él usando los métodos de la clase a la que pertenece.
|
106
|
|
-
|
107
|
|
-###Métodos de una clase
|
108
|
|
-
|
109
|
|
-Los métodos de una clase determinan qué acciones podemos tomar sobre los objetos de esa clase. Los métodos son parecidos a las funciones en el sentido de que pueden recibir parámetros y regresar un resultado. Una forma elemental de conocer los métodos de una clase es leyendo la declaración de la clase. Por ejemplo, lo siguiente es parte de la declaración de la clase `Bird` en el archivo `bird.h`.
|
110
|
|
-
|
111
|
|
----
|
112
|
|
-
|
113
|
|
-
|
114
|
|
-```
|
115
|
|
-class Bird : public QWidget
|
116
|
|
-{
|
117
|
|
-.
|
118
|
|
-.
|
119
|
|
-.
|
120
|
|
- Bird(int , EyeBrowType , QString , QString, QWidget *parent = 0) ;
|
121
|
|
-
|
122
|
|
- int getSize() const;
|
123
|
|
- EyeBrowType getEyebrow() const ;
|
124
|
|
- QString getFaceColor() const;
|
125
|
|
- QString getEyeColor() const;
|
126
|
|
- Qt::GlobalColor getColor(QString) const;
|
127
|
|
-
|
128
|
|
- void setSize(int) ;
|
129
|
|
- void setEyebrow(EyeBrowType) ;
|
130
|
|
- void setFaceColor(QString) ;
|
131
|
|
- void setEyeColor(QString) ;
|
132
|
|
-.
|
133
|
|
-.
|
134
|
|
-.
|
135
|
|
-};
|
136
|
|
-```
|
137
|
|
----
|
138
|
|
-
|
139
|
|
-Una vez creado un objeto, sus métodos proveen la única forma de cambiar sus atributos u obtener información o cómputos de los mismos. Es por esto que comúnmente se llama *interface* al conjunto de métodos de una clase. Los métodos son el interface entre el usuario de un objeto y su contenido.
|
140
|
|
-
|
141
|
|
-
|
142
|
|
-En general, en cada clase se definen los prototipos de los métodos para construir los objetos, y para buscar, manipular y guardar los datos. Lo siguiente es el formato general del prototipo de un método:
|
143
|
|
-
|
144
|
|
-`tipoDevolver nombreMetodo(tipo de los parámetros);`
|
145
|
|
-
|
146
|
|
-Luego, en el código del proyecto se escribe la función correspondiente al método, comenzando con un encabezado que incluye el nombre de la clase a la cuál pertenece la función:
|
147
|
|
-
|
148
|
|
-`TipoDevolver NombreClase::NombreMetodo(parámetros)`
|
149
|
|
-
|
150
|
|
-Para que los objetos que sean instancia de una clase puedan tener acceso a las variables privadas de la clase se declaran métodos que sean públicos y que den acceso a estas clases (ver abajo "setters" y "getters"). Es preferible utilizar variables privadas y accederlas mediante los "setters" y "getters", a declararlas públicas ya que de esta manera el objeto que está asociado a estas variables tiene el control de los cambios que se hacen.
|
151
|
|
-
|
152
|
|
-Para invocar un método escribimos el nombre del objeto, seguido de un punto y luego el nombre del método:
|
153
|
|
-
|
154
|
|
-`nombreObjeto.nombreMetodo(argumentos);`
|
155
|
|
-
|
156
|
|
-
|
157
|
|
-
|
158
|
|
-####Constructores
|
159
|
|
-
|
160
|
|
-Los primeros métodos de una clase que debemos entender son los *constructores*.Una clase puede tener múltiples constructores. Uno de los constructores será invocado automáticamente cada vez que se crea un objeto de esa clase. En la mayoría de los casos, los constructores se utilizan para inicializar los valores de los atributos del objeto. Para poder crear objetos de una clase, debemos conocer cuáles son sus constructores.
|
161
|
|
-
|
162
|
|
-En C++, los constructores tienen el mismo nombre que la clase. No se declara el tipo que devuelven porque estas funciones no devuelven ningún valor. Su declaración (incluida en la definición de la clase) es algo así:
|
163
|
|
-
|
164
|
|
-`nombreMetodo(tipo de los parámetros);`
|
165
|
|
-
|
166
|
|
-El encabezado de la función será algo así:
|
167
|
|
-
|
168
|
|
-`NombreClase::NombreMetodo(parámetros)`
|
169
|
|
-
|
170
|
|
-La clase `Bird` que estarás usando en la sesión de hoy tiene dos constructores (funciones sobrecargadas):
|
171
|
|
-
|
172
|
|
-`Bird (QWidget *parent=0)`
|
173
|
|
-
|
174
|
|
-`Bird (int, EyeBrowType, QString, QString, QWidget *parent=0)`
|
175
|
|
-
|
176
|
|
-Puedes ver las declaraciones de los prototipos de estos métodos en la declaración de la clase `Bird` en el archivo `bird.h` del proyecto. La documentación se encuentra en http://ada.uprrp.edu/~ranazario/bird-html/class_bird.html. El primer constructor, `Bird (QWidget *parent=0)`, es un método que se puede invocar con uno o ningún argumento. Si al invocarlo no se usa argumento, el parámetro de la función toma el valor 0.
|
177
|
|
-
|
178
|
|
-El constructor de una clase que se puede invocar sin usar argumentos es el *constructor* "*default*" de la clase; esto es, el constructor que se invoca cuando creamos un objeto usando una instrucción como:
|
179
|
|
-
|
180
|
|
-`Bird pitirre;`
|
181
|
|
-
|
182
|
|
-Puedes ver las implementaciones de los métodos de la clase Birden el archivo `bird.cpp`. Nota que el primer constructor, `Bird (QWidget *parent=0)`, asignará valores aleatorios ("random") a cada uno de los atributos del objeto. Más adelante hay una breve explicación de la función `randInt`.
|
183
|
|
-
|
184
|
|
-Dale un vistazo a la documentación del segundo constructor, `Bird (int, EyeBrowType, QString, QString, QWidget *parent=0)`. Esta función requiere cuatro argumentos y tiene un quinto argumento que es opcional porque tiene un valor por defecto. Una manera para usar este constructor es creando un objeto como el siguiente:
|
185
|
|
-
|
186
|
|
-`Bird guaraguao(200, Bird::UPSET, "blue", "red");`
|
187
|
|
-
|
188
|
|
-
|
189
|
|
-####"Setters" ("mutators")
|
190
|
|
-
|
191
|
|
-Las clases proveen métodos para modificar los valores de los atributos de un objeto que se ha creado. Estos métodos se llaman "*setters*" o "*mutators*". Usualmente se declara un "setter" por cada atributo que tiene la clase. La clase `Bird` tiene los siguientes "setters":
|
192
|
|
-
|
193
|
|
-* `void setSize (int)`
|
194
|
|
-* `void setEyebrow (EyeBrowType)`
|
195
|
|
-* `void setFaceColor (QString)`
|
196
|
|
-* `void setEyeColor (QString)`
|
197
|
|
-
|
198
|
|
-
|
199
|
|
-Puedes ver las declaraciones de los métodos en la Figura 1 y en la declaración de la clase `Bird` en `bird.h`, y la implementación de algunos de los métodos en `bird.cpp`. El código en el siguiente ejemplo crea el objeto `bobo` de la clase `Bird` y luego cambia su tamaño a 333.
|
200
|
|
-
|
201
|
|
-```
|
202
|
|
-Bird bobo;
|
203
|
|
-bobo.setSize(333);
|
204
|
|
-```
|
205
|
|
-
|
206
|
|
-
|
207
|
|
-####"Getters" ("accessors")
|
208
|
|
-
|
209
|
|
-Las clases también proveen métodos para acceder ("get") el valor del atributo de un objeto. Estos métodos se llaman "*getters*" o "*accessors*". Usualmente se declara un "getter" por cada atributo que tiene la clase. La clase `Bird` tiene los siguientes "getters":
|
210
|
|
-
|
211
|
|
-* `int getSize ()`
|
212
|
|
-* `EyeBrowType getEyebrow ()`
|
213
|
|
-* `QString getFaceColor ()`
|
214
|
|
-* `QString getEyeColor ()`
|
215
|
|
-
|
216
|
|
-
|
217
|
|
-Puedes ver las declaraciones de los métodos en la Figura 1 y en la declaración de la clase `Bird` en `bird.h`, y las implementaciones de algunos de métodos en `bird.cpp`. El código en el siguiente ejemplo crea el objeto `piolin` de la clase `Bird` e imprime su tamaño.
|
218
|
|
-
|
219
|
|
-```
|
220
|
|
-Bird piolin;
|
221
|
|
-cout << piolin.getSize();
|
222
|
|
-```
|
223
|
|
-
|
224
|
|
-####Otras funciones o métodos que utilizarás en esta experiencia de laboratorio
|
225
|
|
-
|
226
|
|
-**MainWindow:** El archivo `mainwindow.h` contiene la declaración de una clase llamada `MainWindow`. Los objetos que sean instancias de esta clase podrán utilizar los métodos sobrecargados
|
227
|
|
-
|
228
|
|
-`void MainWindow::addBird(int x, int y, Bird &b)`
|
229
|
|
-
|
230
|
|
-`void MainWindow::addBird(Bird &b)`
|
231
|
|
-
|
232
|
|
-que añadirán a la pantalla un dibujo del objeto de la clase `Bird` que es recibido como argumento. El código en el siguiente ejemplo crea un objeto `w` de la clase `MainWindow`, crea un objeto `zumbador` de la clase `Bird` y lo añade a la posición (200,200) de la pantalla `w` usando el primer método.
|
233
|
|
-
|
234
|
|
-
|
235
|
|
-
|
236
|
|
-```
|
237
|
|
-MainWindow w;
|
238
|
|
-Bird zumbador;
|
239
|
|
-w.addBird(200,200,zumbador);
|
240
|
|
-```
|
241
|
|
-
|
242
|
|
-
|
243
|
|
----
|
244
|
|
-
|
245
|
|
-![figure1.png](images/figure1.png)
|
246
|
|
-
|
247
|
|
-**Figura 1.** Ventana `w` con la imagen del objeto `zumbador` en la posición (200, 200).
|
248
|
|
-
|
249
|
|
-
|
250
|
|
----
|
251
|
|
-
|
252
|
|
-
|
253
|
|
-
|
254
|
|
-**¡Importante!** No es suficiente solo crear los objetos `Bird` para que éstos aparezcan en la pantalla. Es necesario usar uno de los métodos `addBird` para que el dibujo aparezca en la pantalla.
|
255
|
|
-
|
256
|
|
-
|
257
|
|
-**randInt:** La clase `Bird` incluye el método
|
258
|
|
-
|
259
|
|
-`int Bird::randInt(int min, int max)`
|
260
|
|
-
|
261
|
|
-para generar números enteros aleatorios ("random") en el rango [min, max]. El método `randInt` depende de otra función para generar números aleatorios que requiere un primer elemento o *semilla* para ser evaluada. En este proyecto, ese primer elemento se genera con la invocación `srand(time(NULL)) ;`.
|
262
|
|
-
|
263
|
|
-
|
264
|
|
----
|
265
|
|
-
|
266
|
|
----
|
267
|
|
-
|
268
|
|
-
|
269
|
|
-## Sesión de laboratorio
|
270
|
|
-
|
271
|
|
-###Ejercicio 1: Estudiar las reglas de herencia de la familia *Birds*
|
272
|
|
-
|
273
|
|
-#### La familia *Birds*
|
274
|
|
-
|
275
|
|
-Juana y Abelardo, mamá y papá pájaros, están a punto de tener un bebé al que llamarán Piolín. Al igual que los pájaros reales, los "pájaros Qt" esperan que sus bebés tengan atributos heredados de su madre y su padre.
|
276
|
|
-
|
277
|
|
-Al terminar esta experiencia de laboratorio tu programa creará dos pájaros (Juana y Abelardo) con características aleatorias y un tercer pájaro (Piolín), con características determinadas por las características de sus padres, siguiendo un conjunto de reglas parecidas a la reglas de herencia genética.
|
278
|
|
-
|
279
|
|
-#### Reglas de herencia
|
280
|
|
-
|
281
|
|
-**Color de ojos**
|
282
|
|
-
|
283
|
|
-El bebé siempre hereda el color de ojos de la madre.
|
284
|
|
-
|
285
|
|
-**Tamaño**
|
286
|
|
-
|
287
|
|
-El tamaño del bebé es el más pequeño entre el tamaño del padre o de la madre.
|
288
|
|
-
|
289
|
|
-**Color de la cara**
|
290
|
|
-
|
291
|
|
-La dominancia de los genes del color de la cara está dada por la siguiente lista (en inglés), ordenada desde el color más dominante al color menos dominante:
|
292
|
|
-
|
293
|
|
-1. blue
|
294
|
|
-2. green
|
295
|
|
-3. red
|
296
|
|
-4. white
|
297
|
|
-5. yellow
|
298
|
|
-
|
299
|
|
-El bebé heredará el color de cara más dominante de los colores de sus padres. Por ejemplo, un bebé cuya madre tiene la cara verde y su padre tiene la cara blanca, tendrá cara verde.
|
300
|
|
-
|
301
|
|
-**Cejas**
|
302
|
|
-
|
303
|
|
-La dominancia de los genes de las cejas está dada por la siguiente lista (en inglés), ordenada desde las cejas más dominantes a las cejas menos dominantes:
|
304
|
|
-
|
305
|
|
-1. Bird::ANGRY
|
306
|
|
-2. Bird::BUSHY
|
307
|
|
-3. Bird::UNI
|
308
|
|
-4. Bird::UPSET
|
309
|
|
-
|
310
|
|
-Los genes de las cejas siguen las siguientes reglas:
|
311
|
|
-
|
312
|
|
-a. Si ambos padres tienen cejas "angry", el bebé tendrá cejas "unibrow".
|
313
|
|
-b. Si ambos padres tienen cejas "unibrow", el bebé tendrá cejas "upset".
|
314
|
|
-c. En los otros casos, el bebé heredará las cejas más dominantes de las cejas de sus padres.
|
315
|
|
-
|
316
|
|
-
|
317
|
|
-###Ejercicio 2: Estudiar la función `main`
|
318
|
|
-
|
319
|
|
-**Instrucciones**
|
320
|
|
-
|
321
|
|
-1. Carga a Qt el proyecto `Conditionals-BirthOfABird` haciendo doble "click" en el archivo `Conditionals-BirthOfABird.pro` que se encuentra en la carpeta `Documents/eip/Conditionals-BirthOfABird` de tu computadora. También puedes ir a `http://bitbucket.org/eip-uprrp/conditionals-birthofabird` para descargar la carpeta `Conditionals-BirthOfABird` a tu computadora.
|
322
|
|
-
|
323
|
|
-2. Configura el proyecto.
|
324
|
|
-
|
325
|
|
- **Importante:** En la pantalla "Configure Project", selecciona la configuración Qt 5.3 o Qt 5.4 clang 64 bit. Si usas otra configuración el proyecto no compilará.
|
326
|
|
-
|
327
|
|
-3. Compila y corre el proyecto. Debes ver una pantalla con dos pájaros que representan a Juana y Abelardo. Luego de un segundo, serás testigo del nacimiento de su bebé Piolín. Sin embargo, este Piolín pudo ser haber volado de otro nido y no ser su hijo, tendrá características aleatorias.
|
328
|
|
-
|
329
|
|
-4. Abre el archivo `main.cpp` (no harás cambios a ningún otro archivo de este proyecto). Estudia la función `main`. NO harás cambios a la función `main`. Nota que la función `main` esencialmente hace dos cosas:
|
330
|
|
- a. Crea los tres pájaros y añade dos de ellos a la pantalla.
|
331
|
|
-b. Crea un cronómetro ("timer") que espera un segundo y luego invoca a la función `birth` pasándole una referencia a la ventana y a los tres pájaros.
|
332
|
|
-
|
333
|
|
----
|
334
|
|
-
|
335
|
|
-![funcionMain.png](images/funcionMain.png)
|
336
|
|
-
|
337
|
|
-**Figura 2.** Función `main`.
|
338
|
|
-
|
339
|
|
----
|
340
|
|
-
|
341
|
|
-
|
342
|
|
-###Ejercicio 3: Escribir el código para determinar las características de Piolín
|
343
|
|
-
|
344
|
|
-Estudia el encabezado de la función `birth`. En esta función, escribe el código necesario para que el bebé Piolín tenga las características dictadas por las reglas de herencia explicadas anteriormente.
|
345
|
|
-
|
346
|
|
-
|
347
|
|
-
|
348
|
|
----
|
349
|
|
-
|
350
|
|
- ![funcionBirth.png](images/funcionBirth.png)
|
351
|
|
-
|
352
|
|
- **Figura 3.** Función `birth`.
|
353
|
|
-
|
354
|
|
----
|
355
|
|
-
|
356
|
|
----
|
357
|
|
-
|
358
|
|
-##Entregas
|
359
|
|
-
|
360
|
|
-Utiliza "Entrega" en Moodle para entregar el archivo `main.cpp` con las modificaciones que hiciste a la función `birth`. Recuerda utilizar buenas prácticas de programación, incluir el nombre de los programadores y documentar tu programa.
|
361
|
|
-
|
362
|
|
-
|
363
|
|
-
|
364
|
|
----
|
365
|
|
-
|
366
|
|
----
|
367
|
|
-
|
368
|
|
-##Referencias
|
369
|
|
-
|
370
|
|
-
|
371
|
|
-
|
372
|
|
-https://sites.google.com/a/wellesley.edu/wellesley-cs118-spring13/lectures-labs/lab-2
|
373
|
|
-
|
374
|
|
----
|
375
|
|
-
|
376
|
|
----
|
377
|
|
-
|
378
|
|
----
|
379
|
|
-
|
380
|
|
-[English](#markdown-header-decision-structures-birth-of-a-bird) | [Español](#markdown-header-estructuras-de-decision-nacimiento-de-un-pajaro)
|
381
|
|
-
|
382
|
|
-#Decision Structures - Birth of a Bird
|
383
|
|
-
|
384
|
|
-
|
385
|
|
-![main1.png](images/main1.png)
|
386
|
|
-![main2.png](images/main2.png)
|
387
|
|
-![main3.png](images/main3.png)
|
388
|
|
-
|
389
|
|
----
|
390
|
|
-
|
391
|
|
----
|
392
|
|
-
|
393
|
|
-
|
394
|
|
-##Classes and objects in C++
|
395
|
|
-
|
396
|
|
-An *object* es an entity that contains data and procedures to manipulate them. Similar to how each variable has a *type* of data associated to it, each object has a *class* associated that describes the properties of the objects: its data (*attributes*), and the procedures that can be used to manipulate its data (*methods*).
|
397
|
|
-
|
398
|
|
-To define and use an object it is not necessary to know all of the details about the methods of the object, but you must know how to create it and how to interact with it. The necessary information is available in the class' documentation. Before creating objects of any class we should familiarize ourselves with its documentation. The documentation indicates, among other things, what entity is trying to be represented in the class, and its interface or methods available to manipulate the objects of the class.
|
399
|
|
-
|
400
|
|
-Take a look at the documentation of the `Bird` class which can be found in [this link.](http://ada.uprrp.edu/~ranazario/bird-html/class_bird.html).
|
401
|
|
-
|
402
|
|
-###Classes
|
403
|
|
-
|
404
|
|
-A class is a piece of code that describes how objects will be. The class’ declaration establishes the attributes that each of the objects of the class will have, and the methods that it can invoke.
|
405
|
|
-
|
406
|
|
-If it isn't specified otherwise, the attributes and methods defined in a class will be private. This means that the variables can only be accessed and changed by the methods of the class (*constructors*, *setters*, and *getters*, among others).
|
407
|
|
-
|
408
|
|
-The following is the skeleton of the declaration of a class:
|
409
|
|
-
|
410
|
|
----
|
411
|
|
-
|
412
|
|
-```
|
413
|
|
- class ClassName
|
414
|
|
- {
|
415
|
|
- // Declarations
|
416
|
|
-
|
417
|
|
- private:
|
418
|
|
- // Declaration of variables or attributes
|
419
|
|
- // and prototype member functions
|
420
|
|
- // that are private for this class
|
421
|
|
-
|
422
|
|
- type privateVar
|
423
|
|
- type nameOfPrivateMemFunc(type of the parameters);
|
424
|
|
-
|
425
|
|
- public:
|
426
|
|
- // Declarations of attributes
|
427
|
|
- // and prototypes of method functions
|
428
|
|
- // that are public for the entire program
|
429
|
|
-
|
430
|
|
- type publicVar;
|
431
|
|
- type nameOfPublicMemFunc(type of the parameters);
|
432
|
|
- };
|
433
|
|
-```
|
434
|
|
----
|
435
|
|
-
|
436
|
|
-You can see the declaration of the `Bird` class in the file `bird.h` included in this laboratory experience's program.
|
437
|
|
-
|
438
|
|
-###Objects
|
439
|
|
-
|
440
|
|
-An object is an entity that contains data (as well as a variable), called its `attributes`, and also contain procedures, called `method`, that are used to manipulate them. The objects are "instances" of a class that are created in a similar manner as how variables are defined:
|
441
|
|
-
|
442
|
|
-`ClassName objectName;`
|
443
|
|
-
|
444
|
|
-By creating an object we have available the methods of the class that the object belongs to.
|
445
|
|
-
|
446
|
|
-###Methods of a class
|
447
|
|
-
|
448
|
|
-The methods of a class determine the actions that we can take on the objects of that class. The methods are similar to functions in the sense that they can receive parameters and return a result. An elementary way to know the methods of a class is reading de class declaration. For example, the following is a section of the declaration of the class `Bird` in the file `bird.h`.
|
449
|
|
-
|
450
|
|
----
|
451
|
|
-
|
452
|
|
-
|
453
|
|
-```
|
454
|
|
-class Bird : public QWidget
|
455
|
|
-{
|
456
|
|
-.
|
457
|
|
-.
|
458
|
|
-.
|
459
|
|
- Bird(int , EyeBrowType , QString , QString, QWidget *parent = 0) ;
|
460
|
|
-
|
461
|
|
- int getSize() const;
|
462
|
|
- EyeBrowType getEyebrow() const ;
|
463
|
|
- QString getFaceColor() const;
|
464
|
|
- QString getEyeColor() const;
|
465
|
|
- Qt::GlobalColor getColor(QString) const;
|
466
|
|
-
|
467
|
|
- void setSize(int) ;
|
468
|
|
- void setEyebrow(EyeBrowType) ;
|
469
|
|
- void setFaceColor(QString) ;
|
470
|
|
- void setEyeColor(QString) ;
|
471
|
|
-.
|
472
|
|
-.
|
473
|
|
-.
|
474
|
|
-};
|
475
|
|
-```
|
476
|
|
-
|
477
|
|
-
|
478
|
|
----
|
479
|
|
-
|
480
|
|
-Once the object is created, its methods provide the only way to change its attributes, to obtain information about them, or to compute with them. This is why the set of methods is commonly called *interface*. The methods are the interface between the object’s user and its content.
|
481
|
|
-
|
482
|
|
-In general, in each class the prototypes of the methods are defined to construct the objects, and to search, manipulate and store the data. The following is a general format of a method prototype:
|
483
|
|
-
|
484
|
|
-`typeReturned methodName(type of the parameters);`
|
485
|
|
-
|
486
|
|
-Afterwards, we write the corresponding function to the method in the project's code, starting with a header that includes the name of the class that the function belongs to:
|
487
|
|
-
|
488
|
|
-`TypeReturned ClassName::MethodName(parameters)`
|
489
|
|
-
|
490
|
|
-We declare public methods within the class so that objects that are instances of a class have permission to access private variables (these are the setters and getters). It's prefered to use private variables and access them through the setters and getters, instead of declaring them public since the object that is associated to these variables has control over the changes that are made.
|
491
|
|
-
|
492
|
|
-To invoke a method we write the name of the object, followed by a period and then the name of the method:
|
493
|
|
-
|
494
|
|
-`objectName.methodName(arguments);`
|
495
|
|
-
|
496
|
|
-
|
497
|
|
-####Constructors
|
498
|
|
-
|
499
|
|
-The first methods of a class that we should understand are the *constructors*. A class can have multiple constructors. One of the constructors will be invoked automatically each time an object of that class is created. In most of the cases, the constructors are used to initialize the values for the object’s attributes. To create objects of a class, we must know which are the constructors of the class.
|
500
|
|
-
|
501
|
|
-
|
502
|
|
-
|
503
|
|
-In C++, the constructors have the same name as the class. The type returned by these functions is not declared since they do not return any value. Their declaration (included in the definition of the class) is like this:
|
504
|
|
-
|
505
|
|
-`methodName(type of the parameters);`
|
506
|
|
-
|
507
|
|
-The function header will be like this:
|
508
|
|
-
|
509
|
|
-`ClassName::MethodName(parameters)`
|
510
|
|
-
|
511
|
|
-The class `Bird` that you will be using in today's session has two constructors (overloaded functions):
|
512
|
|
-
|
513
|
|
-`Bird (QWidget *parent=0)`
|
514
|
|
-
|
515
|
|
-`Bird (int, EyeBrowType, QString, QString, QWidget *parent=0)`
|
516
|
|
-
|
517
|
|
-You can see the declarations of the method prototypes in the declaration of the `Bird` class in the project's `bird.h` file. The documentation can be found in [this link.](http://ada.uprrp.edu/~ranazario/bird-html/class_bird.html) The first constructor, `Bird (QWidget *parent=0)`, is a method that can be invoked with one or no argument. If no argument is used, the function's parameter has a value of 0.
|
518
|
|
-
|
519
|
|
-A class' constructor that can be invoked without using an argument is the class' *default constructor*; that is, the constructor that is invoked when we create an object using an instruction like:
|
520
|
|
-
|
521
|
|
-`Bird pitirre;`
|
522
|
|
-
|
523
|
|
-You can see the implementations of the class `Bird` in the file `bird.cpp`. Note that the first constructor, `Bird (QWidget *parent=0)`, will assign random values to each of the object's attributes. Later on there is a brief explanation for the `randInt` function.
|
524
|
|
-
|
525
|
|
-Have a look at the documentation for the second constructor, `Bird (int, EyeBrowType, QString, QString, QWidget *parent=0)`. This function requires four arguments and has a fifth argument that is optional since it has a default value. One way to use this constructor is creating an object like this:
|
526
|
|
-
|
527
|
|
-`Bird guaraguao(200, Bird::UPSET, "blue", "red");`
|
528
|
|
-
|
529
|
|
-
|
530
|
|
-####Setters (mutators)
|
531
|
|
-
|
532
|
|
-Classes provide methods to modify the values of the attributes of an objected that has been created. These methods are called *setters* or *mutators*. Usually, we declare one setter for each attribute that the class has. The `Bird` class has the following setters:
|
533
|
|
-
|
534
|
|
-* `void setSize (int)`
|
535
|
|
-* `void setEyebrow (EyeBrowType)`
|
536
|
|
-* `void setFaceColor (QString)`
|
537
|
|
-* `void setEyeColor (QString)`
|
538
|
|
-
|
539
|
|
-
|
540
|
|
-You can see the method's declarations in Figure 1 and in the `Bird` class declaration in `bird.h`, and the implementation of the some of the methods in `bird.cpp`. The code in the following example creates the object `bobo` of the `Bird` class and then changes its size to 333.
|
541
|
|
-
|
542
|
|
-```
|
543
|
|
-Bird bobo;
|
544
|
|
-bobo.setSize(333);
|
545
|
|
-```
|
546
|
|
-
|
547
|
|
-####Getters (accessors)
|
548
|
|
-
|
549
|
|
-Classes also provide methods to access (get) the value of the attribute of an object. These methods are called *getters* or *accessors*. We usually declare one getter for each attribute a class has. The `Bird` class has the following getters:
|
550
|
|
-
|
551
|
|
-* `int getSize ()`
|
552
|
|
-* `EyeBrowType getEyebrow ()`
|
553
|
|
-* `QString getFaceColor ()`
|
554
|
|
-* `QString getEyeColor ()`
|
555
|
|
-
|
556
|
|
-You can see the declarations of the methods in Figure 1 and in the `Bird` class declaration in `bird.h`, and the implementations of some of the methods in `bird.cpp`. The code in the following example creates the object `piolin` of the `Bird` class and prints its size:
|
557
|
|
-
|
558
|
|
-```
|
559
|
|
-Bird piolin;
|
560
|
|
-cout << piolin.getSize();
|
561
|
|
-```
|
562
|
|
-
|
563
|
|
-####Other functions or methods you will use in this laboratory experience
|
564
|
|
-
|
565
|
|
-**MainWindow:** The file `mainwindow.h` contains the declaration of a class called `MainWindow`. The objects that are instances of this class will be able to use the overloaded methods
|
566
|
|
-
|
567
|
|
-`void MainWindow::addBird(int x, int y, Bird &b)`
|
568
|
|
-
|
569
|
|
-`void MainWindow::addBird(Bird &b)`
|
570
|
|
-
|
571
|
|
-that will add to the screen a drawing of an object of the `Bird` class that is received as an argument. The code in the following example creates an object `w` of the `MainWindow` class, creates an object `zumbador` of the `Bird` class and adds it in the position (200,200) on the screen `w` using the first method.
|
572
|
|
-
|
573
|
|
-```
|
574
|
|
-MainWindow w;
|
575
|
|
-Bird zumbador;
|
576
|
|
-w.addBird(200,200,zumbador);
|
577
|
|
-```
|
578
|
|
-
|
579
|
|
-
|
580
|
|
----
|
581
|
|
-
|
582
|
|
-![figure1.png](images/figure1.png)
|
583
|
|
-
|
584
|
|
-**Figure 1.** Window `w` with the image of the object `zumbador` in the position (200,200).
|
585
|
|
-
|
586
|
|
-
|
587
|
|
----
|
588
|
|
-
|
589
|
|
-
|
590
|
|
-
|
591
|
|
-**Important!** It's not enough to just create the `Bird` objects so that these appear on the screen. It's necessary to use one of the `addBird` methods to make the drawing appear on the screen.
|
592
|
|
-
|
593
|
|
-**randInt:** The `Bird` class includes the method
|
594
|
|
-
|
595
|
|
-`int Bird::randInt(int min, int max)`
|
596
|
|
-
|
597
|
|
-to generate random numbers in the range [min, max]. The method `randInt` depends on another function to generate random numbers that require a first element or *seed* to be evaluated. In this project, that first element is generated with the function call `srand(time(NULL)) ;`.
|
598
|
|
-
|
599
|
|
----
|
600
|
|
-
|
601
|
|
----
|
602
|
|
-
|
603
|
|
-##Laboratory session
|
604
|
|
-
|
605
|
|
-
|
606
|
|
-###Exercise 1: Study the inheritance rules for the *Birds* family
|
607
|
|
-
|
608
|
|
-#### The *Birds* family
|
609
|
|
-
|
610
|
|
-Juana and Abelardo, mother and father birds, are about to have a baby they will call Piolín. As with real birds, the "Qt birds" expect their babies to have inherited attributes from their mother and father.
|
611
|
|
-
|
612
|
|
-When the laboratory experience is finished, your program will create two birds (Juana and Abelardo) with random characteristics and a third bird (Piolín), with characteristics determined by the parent's characteristics, following a set of rules similar to the rules of genetic inheritance.
|
613
|
|
-
|
614
|
|
-
|
615
|
|
-### Inheritance rules
|
616
|
|
-
|
617
|
|
-**Eye color**
|
618
|
|
-
|
619
|
|
-The baby will always inherit the mother's eye color
|
620
|
|
-
|
621
|
|
-**Size**
|
622
|
|
-
|
623
|
|
-The size of the bird is smallest between the mother's or father's size.
|
624
|
|
-
|
625
|
|
-**Face color**
|
626
|
|
-
|
627
|
|
-The gene dominance for the face color is given by the following list, ordered from color with most dominance color to color with least dominance:
|
628
|
|
-
|
629
|
|
-1. blue
|
630
|
|
-2. green
|
631
|
|
-3. red
|
632
|
|
-4. white
|
633
|
|
-5. yellow
|
634
|
|
-
|
635
|
|
-The baby will inherit the face color most dominant from the parent's colors. For example, a baby whose mother has a green face and whose father has a white face, will have a green face.
|
636
|
|
-
|
637
|
|
-**Eyebrows**
|
638
|
|
-
|
639
|
|
-The gene dominance for the eyebrows is given by the following list, ordered from eyebrows with most dominance to eyebrows with least dominance:
|
640
|
|
-
|
641
|
|
-1. Bird::ANGRY
|
642
|
|
-2. Bird::BUSHY
|
643
|
|
-3. Bird::UNI
|
644
|
|
-4. Bird::UPSET
|
645
|
|
-
|
646
|
|
-The genes in the eyebrows follow these rules:
|
647
|
|
-
|
648
|
|
-a. If both parents have "angry" eyebrows, the baby will have "unibrow" eyebrows.
|
649
|
|
-b. If both parents have "unibrow" eyebrows, the baby will have "upset" eyebrows.
|
650
|
|
-c. In other cases, the baby will inherit the eyebrows with most dominance from the parent's eyebrows.
|
651
|
|
-
|
652
|
|
-
|
653
|
|
-###Exercise 2: Study the `main` function
|
654
|
|
-
|
655
|
|
-**Instructions**
|
656
|
|
-
|
657
|
|
-1. Load the project `Conditionals-BirthOfABird` onto Qt by double clicking the file `Conditionals-BirthOfABird.pro` in the folder `Documents/eip/Conditionals-BirthOfABird` on your computer. You can also go to `http://bitbucket.org/eip-uprrp/conditionals-birthofabird` to download the `Conditionals-BirthOfABird` folder to your computer.
|
658
|
|
-
|
659
|
|
-2. Configure the project.
|
660
|
|
-
|
661
|
|
-**Important:** In the "Configure Project" window, select the configuration Qt 5.3 or Qt 5.4 clang 64 bit. If you use another configuration the project will not compile.
|
662
|
|
-
|
663
|
|
-3. Compile and run the project. You should see a window with two birds that represent Juana and Abelardo. After a second, you will witness the birth of their baby, Piolín. Despite that, this Piolín could have been from another nest and not their son since it has random characteristics.
|
664
|
|
-
|
665
|
|
-4. Open the file `main.cpp` (you will not make changes in any other file in this project). Study the `main` function. You will NOT make changes to the `main` function. Note that the `main` function essentially does two things:
|
666
|
|
- a. Creates three birds and adds two of them to the window.
|
667
|
|
-b. Creates a timer that waits a second and after invokes the `birth` function passing by reference to the window and the three birds.
|
668
|
|
-
|
669
|
|
----
|
670
|
|
-
|
671
|
|
-
|
672
|
|
- ![funcionMain.png](images/funcionMain.png)
|
673
|
|
-
|
674
|
|
- **Figure 2.** `Main` function.
|
675
|
|
-
|
676
|
|
----
|
677
|
|
-
|
678
|
|
-###Exercise 3: Write the code to determine Piolín's characteristics
|
679
|
|
-
|
680
|
|
-Study the header for the `birth` function. In this function, write the necessary code so baby Piolín has the characteristics dictated by the rules of inheritance exposed previously.
|
681
|
|
-
|
682
|
|
----
|
683
|
|
-
|
684
|
|
- ![funcionBirth.png](images/funcionBirth.png)
|
685
|
|
-
|
686
|
|
- **Figure 3.** `Birth` function
|
687
|
|
-
|
688
|
|
----
|
689
|
|
-
|
690
|
|
----
|
691
|
|
-
|
692
|
|
-##Deliverables
|
693
|
|
-
|
694
|
|
-Use "Deliverables" in Moodle to upload the `main.cpp` file with the modifications you made to the `birth` function. Remember to use good programming techniques, include the names of the programmers involved, and to document your program.
|
695
|
|
-
|
696
|
|
-
|
697
|
|
----
|
698
|
|
-
|
699
|
|
----
|
700
|
|
-
|
701
|
|
-##References
|
702
|
|
-
|
703
|
|
-
|
704
|
|
-
|
705
|
|
-https://sites.google.com/a/wellesley.edu/wellesley-cs118-spring13/lectures-labs/lab-2
|
706
|
|
-
|
707
|
|
-
|
708
|
|
-
|
709
|
|
-
|
710
|
|
-
|
711
|
|
-
|
|
1
|
+## [\[English\]](README-en.md) - for README in English
|
|
2
|
+## [\[Spanish\]](README-es.md) - for README in Spanish
|