Differences between revisions 1 and 6 (spanning 5 versions)
Revision 1 as of 2007-12-11 12:36:56
Size: 7040
Comment: Version Inicial
Revision 6 as of 2008-12-04 08:48:56
Size: 8682
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
[[TableOfContents()]]

== Miscelánea de funciones. ==
<<TableOfContents>>

== ==
Line 8: Line 8:
En determinadas ocasiones hace falta tener unos ciertos valores aleatorios, por ejemplo a la hora de programar juegos. En los juegos, muchas veces, hace falta elegir al azar qué carta se va a levantar, dónde se va a poner la mina, etc. Para tomar este tipo de decisiones hacen falta unos valores aleatorios, o sea, al azar o que se acerquen mucho a ello. Por esta necesidad es que se ha implementado en GLib la biblioteca gran.h, que consiste en una estructura de datos GRand y un conjunto de funciones. Estas funciones sirven para inicializar la estructura GRand, darle valores iniciales y obtener números aleatorios de distintos tipos.

Lo de los tipos es en el sentido más informático de la palabra, porque todos son números aleatorios igualmente, con la diferencia de que en unos se obtiene un guint32, gdouble, gboolean (este último, evidentemente no es un número, es un booleano). Después algunas funciones establecen rangos para los números. Vamos, un número aleatorio entre el X y el Y.

Cuando se habla de números pseudoaleatorios, hay que hablar irremediablemente de dos conceptos: PRNG(generador de números pseudo aleatorios) y "semilla".

Un PRNG no es más que una estructura de datos con unos algoritmos asociados que, a partir de un valor inicial, genera secuencias de números en un orden, aparentemente aleatorio o, lo que es lo mismo, al azar y es aparentemente porque no es real; si se tuviera la tecnología y el tiempo suficiente, se podría encontrar un cierto orden lógico en las secuencias y predecirlas, pero eso es otro tema; a los efectos, serán considerados como realmente aleatorios.

En el caso de GLIB, este PRNG, será GRand, que es una estructura que, aunque oculta a la visión del programador, es usada internamente por las funciones de la biblioteca grand.h.

El otro concepto es el de semilla. La semilla, no es más que ese valor inicial del que se hablaba antes. Un valor, a ser posible, bastante aleatorio en sí mismo. Para conseguir esta aleatoriedad, lo que se hace es pasarle este valor a la función correspondiente. En caso de que no se quiera pasar la semilla, el constructor de GRand, ''g_rand_new()'', se encargará de obtener un valor aleatorio de /dev/urandom, si existe, o la hora actual si no existiera.
En determinadas ocasiones es necesario trabajar con valores aleatorios, por ejemplo a la hora de programar juegos. En los juegos, muchas veces, hace falta elegir al azar qué carta se va a levantar, dónde se va a poner la mina, etc. Para tomar este tipo de decisiones hacen falta valores aleatorios, es decir, al azar o que se acerquen mucho a ello. Debido a esta necesidad se ha implementado en GLib la biblioteca gran.h, que consiste en una estructura de datos `GRand` y un conjunto de funciones. Estas funciones sirven para inicializar la estructura `GRand`, darle valores iniciales y obtener números aleatorios de distintos tipos.

La referencia a los tipos en el párrafo anterior es en el sentido s informático de la palabra, porque todos son números aleatorios, con la diferencia de que en unos se obtiene un `guint32`, `gdouble`, `gboolean` (este último, no siendo número, sino un valor booleano). Después algunas funciones establecen rangos para los números. Un número aleatorio entre el X y el Y.

Cuando se habla de números pseudoaleatorios, hay que irremediablemente hablar de dos conceptos: `PRNG` (generador de números pseudo aleatorios) y "semilla".

Un `PRNG` no es más que una estructura de datos con algoritmos asociados que, a partir de un valor inicial, genera secuencias de números en un orden, aparentemente aleatorio o, lo que es lo mismo, al azar y es aparentemente ya que no es real; si se tuviera la tecnología y el tiempo suficiente, se podría encontrar un cierto orden lógico en las secuencias y predecirlas, pero eso es otro tema; a los efectos, serán considerados como realmente aleatorios.

En el caso de GLib, este `PRNG`, será `GRand`, que es una estructura que, aunque oculta a la visión del programador, es usada internamente por las funciones de la biblioteca grand.h.

El otro concepto es el de semilla. La semilla, no es más que un valor inicial mencionado con anterioridad. Un valor, de ser posible, bastante aleatorio en sí mismo. Para conseguir esta aleatoriedad, se le entrega este valor a la función correspondiente. En caso de que no se quiera pasar la semilla, el constructor de `GRand`, ''[[#g_rand_new|g_rand_new()]]'', se encargará de obtener un valor aleatorio de /dev/urandom, si existe, o la hora actual en caso contrario.
Line 21: Line 21:
{{{
{{{#!cplusplus
Line 24: Line 25:
Line 26: Line 28:
`void g_random_set_seed(guint32 semilla);`

Con esta función se establece la semilla para la generación de aleatorios. Estableciendo esta semilla con un mismo número cada vez que se ejecute nuestro código, se obtendrá el mismo resultado para los números aleatorios que generemos. Si se desea que los aleatorios no coincidan nunca no estableceremos la semilla.

`gboolean g_random_boolean();`
<<Anchor(g_random_set_seed)>>
{{{
void g_random_set_seed(guint32 semilla);
}}}


Con esta función se establece la semilla para la generación de aleatorios. Estableciendo esta semilla con un mismo número cada vez que se ejecute nuestro código, se obtendrá el mismo resultado para los números aleatorios que se generen. Si se desea que los valores aleatorios no coincidan nunca, basta con no establecer la semilla.

<<Anchor(g_random_boolean)>>
{{{
gboolean g_random_boolean();
}}}
Line 34: Line 42:
`guint32 g_random_int(void);` <<Anchor(g_random_int)>>
{{{
guint32 g_random_int(void);
}}}
Line 38: Line 49:
`gint32 g_random_int_range(gint32 principio, gint32 end);` <<Anchor(g_random_int_range)>>
{{{
gint32 g_random_int_range(gint32 principio, gint32 end);
}}}
Line 42: Line 56:
`gdouble g_random_double(void);`

Se obtiene un gdouble distribuido sobre el rango [0..1).

`
gdouble g_random_double_range(gdouble principio, gdouble fin);`

Se obtiene un gdouble distribuido sobre el rango[principio..fin).

En todos estos casos, internamente, se ha hecho uso de un tipo de dato: GRand. Si lo que necesitamos es obtener una serie de números aleatorios reproducibles, será una mejor opción trabajar directamente con este dato.

La manera de hacerlo es crear primero un GRand y después trabajar con las funciones del tipo ''g_rand*''.

`GRand *g_rand_new(void);`

Crea un nuevo GRand. Los números aleatorios necesitan una semilla para inicializarse, pero en esta función no se le pasa ninguna, así que se tomaría como semilla un valor de /dev/urandom, si existe, o la hora actual.

`
GRand *g_rand_new_with_seed(guint32 semilla);`

En este caso se crea un GRand usando una semilla.

`
void g_rand_set_seed(GRand *rand, guint32 semilla);`

Con esta función se establece una nueva semilla a un GRand.

`
void g_rand_free(GRand *rand);`

Libera la memoria usada por un GRand.

`
gboolean g_rand_boolean(GRand *rand);`

Devuelve el siguiente booleano aleatorio desde rand.

`
guint32 g_rand_int(GRand *rand);`

Devuelve el siguiente guint32 aleatorio desde rand entre los valores [0..2^32-1].

`gint32 g_rand_int_range(GRand *rand, gint32 principio, gint32 fin);`

Devuelve el siguiente gint32 aleatorio desde rand entre los valores [principio..fin-1].

`gdouble g_rand_double(GRand *rand);`

Devuelve el siguiente gdouble aleatorio desde rand entre los valores [0..1).

`
gdouble g_rand_double_range(GRand *rand, gint32 principio, gint32 fin);`

Devuelve el siguiente gdouble aleatorio desde rand entre los valores [principio..fin).

Con estas funciones se pueden obtener números o series de números pseudoaleatorios, de una manera rápida y fácil. Además con la ventaja añadida que ofrece GLIB de la portabilidad.
<<Anchor(g_random_double)>>
{{{
gdouble g_random_double(void);
}}}


Se obtiene un gdouble distribuido sobre el rango [0..1].

<<Anchor(g_random_double_range
)>>
{{{
gdouble g_random_double_range(gdouble principio, gdouble fin);
}}}


Se obtiene un gdouble distribuido sobre el rango [principio..fin].

En todos estos casos, internamente, se ha hecho uso de un tipo de dato: `GRand`. Si lo que se requiere es obtener una serie de números aleatorios reproducibles, será una mejor opción trabajar directamente con este dato.

La manera de hacerlo es crear primero un `GRand` y después trabajar con las funciones del tipo ''g_rand*''.

<<Anchor(g_rand_new)>>
{{{
GRand *g_rand_new(void);
}}}


Crea un nuevo `GRand`. Los números aleatorios necesitan una semilla para inicializarse, pero en esta función no se le entrega ninguna, así que se utilizará como semilla un valor de /dev/urandom, si existe, o la hora actual en caso contrario.

<<Anchor(g_rand_new_with_seed)>>
{{{
GRand *g_rand_new_with_seed(guint32 semilla);
}}}


En este caso se crea un `GRand` usando una semilla.

<<Anchor(g_rand_set_seed)>>
{{{
void g_rand_set_seed(GRand *rand, guint32 semilla);
}}}


Con esta función se establece una nueva semilla a un `GRand`.

<<Anchor(g_rand_free)>>
{{{
void g_rand_free(GRand *rand);
}}}


Libera la memoria usada por un `GRand`.

<<Anchor(g_rand_boolean)>>
{{{
gboolean g_rand_boolean(GRand *rand);
}}}


Devuelve el siguiente booleano aleatorio desde `rand`.

<<Anchor(g_rand_int)>>
{{{
guint32 g_rand_int(GRand *rand);
}}}


Devuelve el siguiente `guint32` aleatorio desde `rand` entre los valores [0..2^32-1].

<<Anchor(g_rand_int_range)>>
{{{
gint32 g_rand_int_range(GRand *rand, gint32 principio, gint32 fin);
}}}


Devuelve el siguiente `gint32` aleatorio desde `rand` entre los valores [principio..fin-1].

<<Anchor(g_rand_double)>>
{{{
gdouble g_rand_double(GRand *rand);
}}}


Devuelve el siguiente `gdouble` aleatorio desde `rand` entre los valores [0..1].

<<Anchor(g_rand_double_range
)>>
{{{
gdouble g_rand_double_range(GRand *rand, gint32 principio, gint32 fin);
}}}


Devuelve el siguiente `gdouble` aleatorio desde `rand` entre los valores [principio..fin].

Con estas funciones se pueden obtener números o series de números pseudoaleatorios, de una manera rápida y fácil. Además con la ventaja añadida de la portabilidad que nos provee GLib.
Line 94: Line 141:
Muchas veces, en los desarrollos de software, es necesario conocer e interactuar con información del entorno en el cual se esté trabajando. Por ejemplo, en un momento dado, podría ser necesario conocer información del usuario como su nombre, su directorio de trabajo o el directorio donde se pueda almacenar información temporal. Para todas estas acciones e incluso algunas más, se dispone de las siguientes funciones.

`gchar* g_get_user_name (void);`

`gchar* g_get_home_dir (void);`

`gchar* g_get_tmp_dir(void);`

`gchar* g_get_current_dir(void);`

Después de haber visto la sintaxis de estas funciones no debe ser muy difícil imaginarse para qué sirve cada una, pero por si queda alguna duda, la primera devolverá el nombre del usuario que esté ejecutando el programa en ese momento; la segunda, su directorio de trabajo; la tercera, el directorio temporal habilitado en su sistema para ese fin y la última función nos devolverá el directorio en el que se esté trabajando actualmente.

Estas funciones nos pueden resultar útiles, pero para aquellos que provengan del universo UNIX o GNU/Linux puede que no les sea suficiente. Esto es debido a que, en este tipo de sistemas operativos, el uso de variables de entorno en sus diferentes shells es muy extendido y en un momento dado, les interesaría recurrir a ellas. Para ello está la función ''g_getenv''. La cual es realmente agradable de usar ya que sólo necesitamos pasarle como parámetro la variable que necesitemos y esta función nos devolverá su valor en una cadena.

`gchar* g_getenv (const gchar * variable );`
Muchas veces, en el desarrollo de aplicaciones, es necesario conocer e interactuar con información del entorno en el cual se esté trabajando. Por ejemplo, en un momento dado, podría ser necesario conocer información del usuario como su nombre, su directorio de trabajo o el directorio donde se pueda almacenar información temporal. Para todas estas acciones e incluso algunas más, se dispone de las siguientes funciones.

<<Anchor(g_get_user_name)>>
{{{
gchar* g_get_user_name (void);
}}}

<<Anchor(g_get_home_dir)>>
{{{
gchar* g_get_home_dir (void);
}}}

<<Anchor(g_get_tmp_dir)>>
{{{
gchar* g_get_tmp_dir(void);
}}}

<<Anchor(g_get_current_dir)>>
{{{
gchar* g_get_current_dir(void);
}}}

Después de haber visto la sintaxis de estas funciones no resulta muy difícil identificar para qué sirve cada una, pero por si queda alguna duda, la primera devolverá el nombre del usuario que esté ejecutando el programa en ese momento; la segunda, su directorio de trabajo; la tercera, el directorio temporal habilitado en su sistema para ese fin y la última función devolverá el directorio en el que se esté trabajando actualmente.

Estas funciones pueden resultar útiles, pero para aquellos que provengan del universo UNIX o GNU/Linux puede que no sea suficiente. Esto es debido a que, en este tipo de sistemas operativos, el uso de variables de entorno en sus diferentes shells es muy extendido y en un momento dado, podrá requerirse recurrir a ellas. Para ello existe la función ''[[#g_getenv|g_getenv]]''. La cual es realmente simple de utilizar ya que sólo requiere como parámetro la variable que se necesite y esta función devolverá su valor en una cadena.

<<Anchor(g_getenv)>>
{{{
gchar* g_getenv (const gchar * variable );
}}}

'''Ejemplo 6-5.1. Obtención de variables de entorno.'''
{{{#!cplusplus
/* ejemplo de como obtener información sobre las variables de entorno */
#include <glib.h>

int
main ()
{
        g_print("Yo soy el usuario %s\n", g_get_user_name());
        g_print("Vivo en %s\n", g_get_home_dir());
        g_print("Puedo escribir archivos temporales en %s\n", g_get_tmp_dir());
        g_print("Y ejecuto este programa desde %s\n", g_get_current_dir());
        g_print("Mi interprete de comandos es %s\n", g_getenv("SHELL"));

        return 0;
}
}}}

Lo cual podría entregarnos un resultado similar a:

{{{
Yo soy el usuario basilio
Vivo en /home/basilio
Puedo escribir archivos temporales en /tmp
Y ejecuto este programa desde /home/basilio/Code/ejemplos
Mi interprete de comandos es /bin/bash
}}}
Line 111: Line 201:
'''''Volver a:''''' [:Documentacion/Desarrollo/Glib:GLib] '''''Volver a:''''' [[Documentacion/Desarrollo/Glib|GLib]]

Miscelánea de funciones

Números aleatorios.

En determinadas ocasiones es necesario trabajar con valores aleatorios, por ejemplo a la hora de programar juegos. En los juegos, muchas veces, hace falta elegir al azar qué carta se va a levantar, dónde se va a poner la mina, etc. Para tomar este tipo de decisiones hacen falta valores aleatorios, es decir, al azar o que se acerquen mucho a ello. Debido a esta necesidad se ha implementado en GLib la biblioteca gran.h, que consiste en una estructura de datos GRand y un conjunto de funciones. Estas funciones sirven para inicializar la estructura GRand, darle valores iniciales y obtener números aleatorios de distintos tipos.

La referencia a los tipos en el párrafo anterior es en el sentido más informático de la palabra, porque todos son números aleatorios, con la diferencia de que en unos se obtiene un guint32, gdouble, gboolean (este último, no siendo número, sino un valor booleano). Después algunas funciones establecen rangos para los números. Un número aleatorio entre el X y el Y.

Cuando se habla de números pseudoaleatorios, hay que irremediablemente hablar de dos conceptos: PRNG (generador de números pseudo aleatorios) y "semilla".

Un PRNG no es más que una estructura de datos con algoritmos asociados que, a partir de un valor inicial, genera secuencias de números en un orden, aparentemente aleatorio o, lo que es lo mismo, al azar y es aparentemente ya que no es real; si se tuviera la tecnología y el tiempo suficiente, se podría encontrar un cierto orden lógico en las secuencias y predecirlas, pero eso es otro tema; a los efectos, serán considerados como realmente aleatorios.

En el caso de GLib, este PRNG, será GRand, que es una estructura que, aunque oculta a la visión del programador, es usada internamente por las funciones de la biblioteca grand.h.

El otro concepto es el de semilla. La semilla, no es más que un valor inicial mencionado con anterioridad. Un valor, de ser posible, bastante aleatorio en sí mismo. Para conseguir esta aleatoriedad, se le entrega este valor a la función correspondiente. En caso de que no se quiera pasar la semilla, el constructor de GRand, g_rand_new(), se encargará de obtener un valor aleatorio de /dev/urandom, si existe, o la hora actual en caso contrario.

Para usar este generador de números pseudo aleatorios, es necesario incluir la biblioteca grand.h.

   1 #include <grand.h>
   2 

Para obtener números aleatorios rápidamente se pueden usar las siguientes funciones:

void g_random_set_seed(guint32 semilla);

Con esta función se establece la semilla para la generación de aleatorios. Estableciendo esta semilla con un mismo número cada vez que se ejecute nuestro código, se obtendrá el mismo resultado para los números aleatorios que se generen. Si se desea que los valores aleatorios no coincidan nunca, basta con no establecer la semilla.

gboolean g_random_boolean();

Con esta función, se obtiene un booleano aleatorio.

guint32 g_random_int(void);

Se obtiene un gunt32 distribuido sobre el rango [0..2^32-1].

gint32 g_random_int_range(gint32 principio, gint32 end);

Se obtiene un gint32 distribuido sobre el rango [principio..fin-1].

gdouble g_random_double(void);

Se obtiene un gdouble distribuido sobre el rango [0..1].

gdouble g_random_double_range(gdouble principio, gdouble fin);

Se obtiene un gdouble distribuido sobre el rango [principio..fin].

En todos estos casos, internamente, se ha hecho uso de un tipo de dato: GRand. Si lo que se requiere es obtener una serie de números aleatorios reproducibles, será una mejor opción trabajar directamente con este dato.

La manera de hacerlo es crear primero un GRand y después trabajar con las funciones del tipo g_rand*.

GRand *g_rand_new(void);

Crea un nuevo GRand. Los números aleatorios necesitan una semilla para inicializarse, pero en esta función no se le entrega ninguna, así que se utilizará como semilla un valor de /dev/urandom, si existe, o la hora actual en caso contrario.

GRand *g_rand_new_with_seed(guint32 semilla);

En este caso se crea un GRand usando una semilla.

void g_rand_set_seed(GRand *rand, guint32 semilla);

Con esta función se establece una nueva semilla a un GRand.

void g_rand_free(GRand *rand);

Libera la memoria usada por un GRand.

gboolean g_rand_boolean(GRand *rand);

Devuelve el siguiente booleano aleatorio desde rand.

guint32 g_rand_int(GRand *rand);

Devuelve el siguiente guint32 aleatorio desde rand entre los valores [0..2^32-1].

gint32 g_rand_int_range(GRand *rand, gint32 principio, gint32 fin);

Devuelve el siguiente gint32 aleatorio desde rand entre los valores [principio..fin-1].

gdouble g_rand_double(GRand *rand);

Devuelve el siguiente gdouble aleatorio desde rand entre los valores [0..1].

gdouble g_rand_double_range(GRand *rand, gint32 principio, gint32 fin);

Devuelve el siguiente gdouble aleatorio desde rand entre los valores [principio..fin].

Con estas funciones se pueden obtener números o series de números pseudoaleatorios, de una manera rápida y fácil. Además con la ventaja añadida de la portabilidad que nos provee GLib.

Funciones de información sobre entorno.

Muchas veces, en el desarrollo de aplicaciones, es necesario conocer e interactuar con información del entorno en el cual se esté trabajando. Por ejemplo, en un momento dado, podría ser necesario conocer información del usuario como su nombre, su directorio de trabajo o el directorio donde se pueda almacenar información temporal. Para todas estas acciones e incluso algunas más, se dispone de las siguientes funciones.

gchar* g_get_user_name (void);

gchar* g_get_home_dir (void);

gchar* g_get_tmp_dir(void);

gchar* g_get_current_dir(void);

Después de haber visto la sintaxis de estas funciones no resulta muy difícil identificar para qué sirve cada una, pero por si queda alguna duda, la primera devolverá el nombre del usuario que esté ejecutando el programa en ese momento; la segunda, su directorio de trabajo; la tercera, el directorio temporal habilitado en su sistema para ese fin y la última función devolverá el directorio en el que se esté trabajando actualmente.

Estas funciones pueden resultar útiles, pero para aquellos que provengan del universo UNIX o GNU/Linux puede que no sea suficiente. Esto es debido a que, en este tipo de sistemas operativos, el uso de variables de entorno en sus diferentes shells es muy extendido y en un momento dado, podrá requerirse recurrir a ellas. Para ello existe la función g_getenv. La cual es realmente simple de utilizar ya que sólo requiere como parámetro la variable que se necesite y esta función devolverá su valor en una cadena.

gchar* g_getenv (const gchar * variable );

Ejemplo 6-5.1. Obtención de variables de entorno.

   1 /* ejemplo de como obtener información sobre las variables de entorno */
   2 #include <glib.h>
   3 
   4 int
   5 main ()
   6 {
   7         g_print("Yo soy el usuario %s\n", g_get_user_name());
   8         g_print("Vivo en %s\n", g_get_home_dir());
   9         g_print("Puedo escribir archivos temporales en %s\n", g_get_tmp_dir());
  10         g_print("Y ejecuto este programa desde %s\n", g_get_current_dir());
  11         g_print("Mi interprete de comandos es %s\n", g_getenv("SHELL"));
  12 
  13         return 0;
  14 }

Lo cual podría entregarnos un resultado similar a:

Yo soy el usuario basilio
Vivo en /home/basilio
Puedo escribir archivos temporales en /tmp
Y ejecuto este programa desde /home/basilio/Code/ejemplos
Mi interprete de comandos es /bin/bash


Volver a: GLib

Documentacion/Desarrollo/Glib/MiscelaneaDeFunciones (last edited 2008-12-04 08:48:56 by localhost)