Universidad de Costa Rica
Escuela de Ciencias de la Computación e Informática
CI-1201 Programación II - 2014b
Profesor Jeisson Hidalgo-Céspedes
Usted ha sido integrado a un equipo de desarrollo de software libre. Actualmente el equipo está trabajando en un comando eficiente en C para reportar propiedades curiosas de números enteros positivos. Al programa se le ha llamado Number Gossip, pues realiza una funcionalidad similar a la aplicación web homónima superando la limitación de números hasta 9999.
Naturalmente el equipo mantiene el código del proyecto bajo control de versiones. El código fuente del Number Gossip se encuentra en la subcarpeta ngossip
del repositorio:
https://github.com/jeissonh/Progra2-14b.git
Clone el repositorio en su máquina de trabajo. Requerirá tener instalado Git y si gusta algún cliente gráfico: TortoiseGit para Windows, RabbitVCS para Linux, SourceTree para OS X. Para clonar el repositorio en una terminal de Unix, emita:
# Vaya a la carpeta donde quiere crear el clon # Si invoca `cd` sin parámetros, irá a la carpeta personal $ cd # Clone el repositorio ahí $ git clone https://github.com/jeissonh/Progra2-14b.git # Vaya al repositorio (puede usar la tecla Tab para completar) $ cd Progra2-14b # Listar el contenido. Verá una subcarpeta para el proyecto Number Gossip $ ls -l drwxr-xr-x 2 jhc jhc 4096 ago 22 15:25 ngossip # Ir a esa carpeta y ver el contenido $ cd ngossip $ ls -l total 368 -rw-r--r-- 1 jhc jhc 319984 ago 22 15:25 catch.hpp -rw-r--r-- 1 jhc jhc 47 ago 22 15:25 main.c -rw-r--r-- 1 jhc jhc 2784 ago 22 15:25 ngossip.c -rw-r--r-- 1 jhc jhc 15837 ago 22 15:25 ngossip.h -rw-r--r-- 1 jhc jhc 156 ago 22 15:25 ngossip.pro -rw-r--r-- 1 jhc jhc 19166 ago 22 15:25 test.cpp -rw-r--r-- 1 jhc jhc 159 ago 22 15:25 test.pro $
La aplicación es modular, pues ha sido pensada con visión a largo plazo. Consta de 3 módulos:
libngossip
. Una biblioteca reutilizable de C que permite conocer las propiedades de números enteros invocando funciones libres.test
. Un programa que prueba la biblioteca libngossip
en busca de errores.ngossip
. Un programa que permite a los usuarios conocer propiedades de números en línea de comandos.libngossip
Consiste de un conjunto de funciones libres, una por cada propiedad de los números enteros. Las declaraciones se encuentran en el archivo de encabezado ngossip.h
, y su implementación en ngossip.c
. Se puede compilar independientemente. Como una biblioteca estática:
$ gcc -std=c11 -c ngossip.c -o ngossip.o $ ar rcs libngossip.a ngossip.o
O como una biblioteca dinámica:
$ gcc -std=c11 -fPIC -c ngossip.c -o ngossip.o $ gcc -shared -Wl,-soname,libngossip.so.1 -o libngossip.so.1.0.1 ngossip.o
test
Es un programa ejecutable que al correrse prueba cada una de las funciones de la biblioteca libngossip
. Consta del archivo test.cpp
y dos bibliotecas: Catch Test Library (catch.hpp
) y naturalmente nuestra biblioteca libngossip
(ngossip.h
y ngossip.c
). Para generar el ejecutable test
se debe utilizar el compilador de C++ por restricción de la biblioteca Catch:
# Compilar el programa de pruebas: $ g++ -Wall -std=c++11 -o test test.cpp ngossip.c # El comando anterior generará un ejecutable probablemente mayor a 1MB: $ ls -lh test -rwxr-xr-x 1 jhc jhc 1,1M ago 22 16:14 test # Para correr todos los casos de prueba, se invoca el ejecutable sin parámetros: $ ./test # Para correr sólo un caso de prueba, por ejemplo, is_prime() se envía por parámetro: $ ./test prime All tests passed (15 assertions in 1 test case)
Si se quieren correr sólo ciertos casos de prueba, se envían los nombres de las funciones sin el prefijo is_
separadas por comas. Por ejemplo, ./test weird, prime
Usted debe agregar al menos una prueba en cada caso del archivo test.cpp
. Introduzca un número grande (pero menor a 10000) en la aplicación web Number Gossip, y de acuerdo a los resultados actualice todos los casos de prueba para ese número. Puede buscar números más grandes en otras fuentes de la web y agregar más pruebas. Verifique que el programa de prueba compile y corre, aunque reporte errores. Comparta sus casos de prueba en el repositorio remoto como se indica en la sección Entrega de la solución.
Colabore con el equipo implementando sus dos propiedades de números enteros. Es decir, implementar el cuerpo de las dos funciones que le fueron asignadas en la tabla de abajo. Mientras implementa las funciones, ejecute con frecuencia el programa de pruebas ./test mifuncion
con el fin de ver que pase las pruebas escogidas. Piense si se pueden realizar optimizaciones para que la función sea más eficiente y aplíquelas. Recuerde verificar que no se hayan roto los casos de prueba. Debe enviar al menos dos commits de Git: al menos uno por cada función implementada.
Estudiante | Prop1 | Prop2 |
---|---|---|
Carlos Luis Rodríguez Núñez | is_perfect | is_primorial |
Christopher Joseph Mora Román | is_ecci1 | is_pentagonal |
Daniel Alonso Arce Madrigal | is_power_of_2 | is_persistent |
Daniel Josué Rojas Leandro | is_ecci2 | is_hypotenuse |
Esteban Raúl Ortega Acuña | is_twin | is_happy |
Fernando (Josué) Pereira Leiva | is_evil | is_fermat |
Fernando González Flores | is_triangular | is_palindrome |
Geovanny de Jesús Zúñiga Salas | is_deficient | is_lazy_caterer |
Heiner Gustavo Vindas Chinchilla | is_product_perfect | is_narcissistic |
Jairo Rojas Rojas | is_square | is_square_free |
Jefferson Cose Toruño | is_fibonacci | is_parasite |
José Alberto Alfaro Quirós | is_factorial | is_mersenne |
José Andrés Víquez Hernández | is_pronic | is_easy_to_remember |
José Manuel Matarrita Campos | is_abundant | is_automorphic |
José Miguel Mesén Campos | is_cube | is_undulating |
Julián Andrés Calvo Murillo | is_compositorial | is_catalan |
Nicole Paola Mora Salazar | is_odious | is_tetrahedral |
Pablo (José) Vargas Cordero | is_repdigit | is_cake |
ngossip
Escriba un comando en C llamado ngossip
que aproveche la biblioteca libngossip
para permitir a los usuarios obtener propiedades de números. Si el comando se invoca con el parámetro --help
imprimirá ayuda:
El programa lee números enteros uno tras otro separados por espacios en blanco. Hay tres fuentes donde el usuario puede indicar los números: (1) por parámetro de invocación:
$ ngossip 13 113 1024 13: prime fibonacci deficient happy lucky odious square-free twin ulam 113: prime deficient evil square-free 1024: prime factors: 2^10 proper factors: 2 4 8 16 32 64 128 256 512 deficient odious power_of_2 powerful practical square $
(2) en un archivo de texto con la opción -i
. El archivo sólo debe contener números separados por espacios en blanco (los cambios en línea también son espacio en blanco):
$ cat nums.txt 248 131 $ ./ngossip -i nums.txt 248: prime factors: 2^3 * 31 proper factors: 2 4 8 31 62 124 deficient odius untouchable 131: prime deficient odious palindrome square-free ulam undulating
(3) en la entrada estándar, cuando no se proveen números en ninguna de las dos fuentes anteriores. Si la entrada estándar no se redirecciona, el comando se comporta de forma interactiva y termina su ejecución cuando se ingresa el carácter fin de archivo (Ctrl+D en Unix, Ctrl+Z en MS-DOS):
$ ./ngossip 8888 8888: prime factors: 2^2 * 3 * 823 proper factors: 2 3 4 6 12 823 1646 2469 3292 4938 abundant apocalyptic_power evil happy untouchable 777 777: prime factors: 3 * 7 * 37 proper factors: 3 7 21 37 111 259 deficient evil lucky palindrome square_free undulating ^D
Para cada uno de los números ingresados, el comando lista en la salida estándar las propiedades que cumplen cada uno de esos números. El parámetro -v
, imprime las propiedades con algún nivel más de detalle:
$ ./ngossip -v 100 100: prime factors: 2^2 * 5^2 proper factors: 2 4 5 10 20 25 50 abundant: the sum of all its proper factors is more than n happy: iterating the sum of the squares of its digits leads to 1 odious: has an odd number of 1's in its binary expansion powerful: for every prime p dividing n, p^2 also divides n practical: all numbers strictly less than n are sums of distinct divisors of n
La opción -l
imprime en la salida estándar la lista de todas las propiedades disponibles en ngossip
. Si el parámetro -v
está disponible, la lista de propiedades se presenta además con la corta descripción, como en ejemplo anterior.
El usuario podría estar interesado en una o unas pocas propiedades que puede escribir por parámetro. En tal caso, el programa sólo prueba dichas propiedades. El usuario podría mezclar los parámetros en cualquier orden. Por ejemplo, la siguiente es una invocación válida que verifica únicamente las propiedades prime
y fibonacci
de los números 3
, 33
, 333
y 33333
, en ese orden seguidos por los que se encuentren en el archivo mas.txt
, y finalmente 3333
. Los números que cumplan esas propiedades las desplegarán con detalles (-v
) en la salida estándar.
$ ./ngossip 3 33 -v 333 prime 33333 fibonacci -i mas.txt 3333
Sin embargo, hay parámetros excluyentes de otros. El parámetro --help
tiene la mayor prioridad. Si es provee se ignoran todos los demás. Lo mismo ocurre con los parámetros --version
y -l
que lista las propiedades. Los parámetros restantes pueden coexistir entre ellos. El parámetro -i FILE
podría repetirse.
Reto 1. Si el usuario quiere probar muchos números secuenciales, tendrá que proveerlos uno a uno, lo cual es tedioso. Haga que el programa pueda entender rangos. Por ejemplo ngossip 1000:1500
muestra las características de los números entre 1000 y 1500 inclusive.
Reto 2. Si el usuario provee varios números o un rango de ellos, puede estar interesado en saber cuáles de ellos cumplen cierta propiedad. En lugar de imprimir las propiedades de cada número por separado, el usuario quiere ver la propiedad y cuales de los números dados la cumplen. A esto se llama transponer la salida, y se indica con el parámetro -t
. Por ejemplo:
test.cpp
y lo envía al repositorio remoto de GitHub.Para presentar su solución, envíe su implementación al repositorio remoto de GitHub. Necesitará crear una cuenta en GitHub.com. Si utiliza un correo distinto al de Mediación Virtual, enviar su nombre de usuario o correo al profesor para agregarlo como colaborador en el repositorio. Luego deberá indicarle al cliente local de Git quién es usted (esto se hace sólo una vez). Por ejemplo:
$ git config --global user.name "Keylor Navas" $ git config --global user.email "keylor@navas.com"
Los cambios que haya hecho estarán en el directorio de trabajo. Debe enviarlos a su repositorio local (el clon que hizo del repositorio de remoto) con un commit, y luego enviarlos al repositorio remoto con un push:
$ git commit -am 'Implementada la propiedad is_xxx()' 2 files changed, 28 insertions(+), 2 deletions(-)
Finalmente "empuje" los commits que haya hecho localmente hacia el repositorio remoto. No olvide actualizar su repositorio local con los cambios remotos antes de enviar los suyos:
$ git pull Already up-to-date. # Si Git dice algo diferente a lo anterior es porque hubo cambios en el repositorio # remoto. Debe revisar que los dos programas y la biblioteca compilen y corran bien # Si quiere puede ver los cambios con un cliente gráfico en la bitácora (log) $ git push
La fecha límite para enviar sus funciones al repositorio de GitHub es el sábado 30 de agosto de 2014 a las 23:55. Si termina antes, puede ayudar en forma presencial a algún compañero(a) a que implemente sus funciones. No significa implementar las funciones de otra persona.