Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2013-09-05 15:01:43 (GMT)
committer Philip Withnall <philip@tecnocode.co.uk>2013-09-05 15:01:43 (GMT)
commita1916c0cf118187a20ce2259608b262aefcbd0b0 (patch)
tree7fedb101e926bef7a470ccdf78ac3e4981cd38f6
parente4f7fb1aa749800a780218d7a3b8b5b052ed2cd0 (diff)
Add Spanish translations of the exercises for part 3
-rw-r--r--Makefile14
-rw-r--r--exercises/es/16_gnome-devel-demos.txt29
-rw-r--r--exercises/es/17_boton-y-etiqueta.py63
-rw-r--r--exercises/es/17_boton-y-etiqueta_solucion.py78
-rw-r--r--exercises/es/18_gtk-a-actividad.txt5
-rw-r--r--exercises/es/19_traduccion.txt4
-rw-r--r--exercises/es/21_actividad-completo.txt29
-rw-r--r--exercises/es/Ejercicio18.activity/activity/activity.info9
-rw-r--r--exercises/es/Ejercicio18.activity/activity/activity.svg163
-rw-r--r--exercises/es/Ejercicio18.activity/ejercicio18.py102
-rw-r--r--exercises/es/Ejercicio18.activity/ejercicio18_solucion.py104
-rwxr-xr-xexercises/es/Ejercicio18.activity/setup.py4
-rw-r--r--exercises/es/Ejercicio19.activity/activity/activity.info9
-rw-r--r--exercises/es/Ejercicio19.activity/activity/activity.svg163
-rw-r--r--exercises/es/Ejercicio19.activity/ejercicio19.py113
-rw-r--r--exercises/es/Ejercicio19.activity/ejercicio19_solucion.py114
-rwxr-xr-xexercises/es/Ejercicio19.activity/setup.py4
-rw-r--r--exercises/es/Ejercicio20.activity/.gitignore3
-rw-r--r--exercises/es/Ejercicio20.activity/activity/activity.info9
-rw-r--r--exercises/es/Ejercicio20.activity/ejercicio20.py78
-rw-r--r--exercises/es/Ejercicio20.activity/images/logonew2.pngbin0 -> 8818 bytes
-rwxr-xr-xexercises/es/Ejercicio20.activity/setup.py4
22 files changed, 1097 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index 964f20c..4a37079 100644
--- a/Makefile
+++ b/Makefile
@@ -37,6 +37,7 @@ ES_EXERCISES = \
13_extender-clase \
14_propiedad \
15_metodos-privadas \
+ 17_boton-y-etiqueta \
$(NULL)
TEX_FILES = \
@@ -67,12 +68,10 @@ ES_PYTHON_FILES = \
EN_EXERCISE_FILES = \
$(EN_PYTHON_FILES) \
- exercises/en/16_gnome-devel-demos.txt \
- exercises/en/17_button-and-label.py \
- exercises/en/17_button-and-label_solution.py \
+ exercises/en/16_gnome-devel-demos.txt \
exercises/en/Exercise18.activity/ \
exercises/en/18_gtk-to-activity.txt \
- exercises/en/Exercise19.activity/ \
+ exercises/en/Exercise19.activity/ \
exercises/en/19_translation.txt \
exercises/en/Exercise20.activity/ \
exercises/en/20_packaging.txt \
@@ -82,6 +81,13 @@ EN_EXERCISE_FILES = \
ES_EXERCISE_FILES = \
$(ES_PYTHON_FILES) \
exercises/es/16_gnome-devel-demos.txt \
+ exercises/es/Ejercicio18.activity/ \
+ exercises/es/18_gtk-a-actividad.txt \
+ exercises/es/Ejercicio19.activity/ \
+ exercises/es/19_traduccion.txt \
+ exercises/es/Ejercicio20.activity/ \
+ exercises/es/20_empaquetado.txt \
+ exercises/es/21_actividad-completo.txt \
$(NULL)
all: $(PDFS) $(ZIPS)
diff --git a/exercises/es/16_gnome-devel-demos.txt b/exercises/es/16_gnome-devel-demos.txt
new file mode 100644
index 0000000..68ccf9a
--- /dev/null
+++ b/exercises/es/16_gnome-devel-demos.txt
@@ -0,0 +1,29 @@
+Ejercicio 16 no se evalúa. En su lugar, usted debe ir a:
+ https://developer.gnome.org/gnome-devel-demos/unstable/tutorial.py.html.es
+y trabajar a través de los siguientes ejemplos. Para cada ejemplo, copiar el
+código en un archivo y ejecutarlo usando Python. Lea la documentación en las
+páginas web y asegurarse de que entiende cómo funciona el ejemplo.
+
+Usted debe buscar en las siguientes páginas del tutorial, como mínimo:
+ • 1.1
+ • 2.1
+ • 2.2
+ • 2.3
+ • 3.1
+ • 4.1
+ • 4.2
+ • 4.3
+ • 4.4
+ • 5.1
+ • 5.2
+ • 5.4
+ • 5.5
+ • 5.7
+ • 7.3
+ • 8.2
+ • 8.3
+ • 9.1
+ • 11.3
+
+Tenga en cuenta que tutorial 14.1 está cubierto por separado en un ejercicio
+posterior.
diff --git a/exercises/es/17_boton-y-etiqueta.py b/exercises/es/17_boton-y-etiqueta.py
new file mode 100644
index 0000000..edd3b6b
--- /dev/null
+++ b/exercises/es/17_boton-y-etiqueta.py
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+# coding=utf-8
+
+"""Este programa debe mostrar una ventana GTK + que contiene un botón y una
+etiqueta.
+
+Debe añadir dos widgets a la caja en la ventana: un Gtk.Button y un Gtk.Label.
+
+El Gtk.Button debe mostrar el texto ‘Cambiar etiqueta’. El Gtk.Label debe
+mostrar el texto ‘Etiqueta inicial’.
+
+Después de añadir los dos widgets, debe conectar un callback a la señal
+‘clicked’ del botón. En este callback, deberá cambiar el texto de la Gtk.Label
+a ‘Etiqueta final’. Esto significa que cuando se ejecuta el programa y se pulsa
+el botón, la etiqueta debe modificar su texto.
+
+Usted puede encontrar documentación de la señal ‘clicked’ de Gtk.Button aquí:
+ https://developer.gnome.org/gtk3/stable/GtkButton.html#GtkButton-clicked
+
+No te olvides de documentar los nuevos métodos que se agregan.
+
+Consejo: No te olvides de llamar al método show() del botón y la etiqueta para
+que sean visibles después de añadirlos a la caja.
+"""
+
+from gi.repository import Gtk
+
+
+class SimpleWindow(Gtk.Window):
+ """Una ventana simple que muestra una etiqueta y un botón."""
+ def __init__(self):
+ super(SimpleWindow, self).__init__(title='Ventana Simple')
+
+ # Establecer un tamaño predeterminado de la ventana.
+ self.set_default_size(200, 200)
+
+ # Configurar un callback de cierre de la ventana. No modifique esto.
+ self.connect('destroy', self.__window_destroy_cb)
+
+ # Agregar una caja de la ventana.
+ box = Gtk.Box()
+ box.set_orientation(Gtk.Orientation.VERTICAL)
+ box.set_spacing(8)
+ box.set_border_width(8)
+ box.show()
+ self.add(box)
+
+ # Debe agregar código aquí para crear y configurar el botón y la
+ # etiqueta. No se olvide de hacer visibles y añadirlos a la caja.
+
+ # Debe agregar un callback para manejar la señal "clicked" del botón y
+ # cambiar el texto de la etiqueta.
+
+ def __window_destroy_cb(self, window):
+ """Callback para salir del programa cuando la ventana está cerrada.
+
+ No modifique esto."""
+ Gtk.main_quit()
+
+
+# Ejecute el programa. No modifique esto.
+SimpleWindow().show()
+Gtk.main()
diff --git a/exercises/es/17_boton-y-etiqueta_solucion.py b/exercises/es/17_boton-y-etiqueta_solucion.py
new file mode 100644
index 0000000..19b60d0
--- /dev/null
+++ b/exercises/es/17_boton-y-etiqueta_solucion.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+# coding=utf-8
+
+"""Este programa debe mostrar una ventana GTK + que contiene un botón y una
+etiqueta.
+
+Debe añadir dos widgets a la caja en la ventana: un Gtk.Button y un Gtk.Label.
+
+El Gtk.Button debe mostrar el texto ‘Cambiar etiqueta’. El Gtk.Label debe
+mostrar el texto ‘Etiqueta inicial’.
+
+Después de añadir los dos widgets, debe conectar un callback a la señal
+‘clicked’ del botón. En este callback, deberá cambiar el texto de la Gtk.Label
+a ‘Etiqueta final’. Esto significa que cuando se ejecuta el programa y se pulsa
+el botón, la etiqueta debe modificar su texto.
+
+Usted puede encontrar documentación de la señal ‘clicked’ de Gtk.Button aquí:
+ https://developer.gnome.org/gtk3/stable/GtkButton.html#GtkButton-clicked
+
+No te olvides de documentar los nuevos métodos que se agregan.
+
+Consejo: No te olvides de llamar al método show() del botón y la etiqueta para
+que sean visibles después de añadirlos a la caja.
+"""
+
+from gi.repository import Gtk
+
+
+class SimpleWindow(Gtk.Window):
+ """Una ventana simple que muestra una etiqueta y un botón."""
+ def __init__(self):
+ super(SimpleWindow, self).__init__(title='Ventana Simple')
+
+ # Establecer un tamaño predeterminado de la ventana.
+ self.set_default_size(200, 200)
+
+ # Configurar un callback de cierre de la ventana. No modifique esto.
+ self.connect('destroy', self.__window_destroy_cb)
+
+ # Agregar una caja de la ventana.
+ box = Gtk.Box()
+ box.set_orientation(Gtk.Orientation.VERTICAL)
+ box.set_spacing(8)
+ box.set_border_width(8)
+ box.show()
+ self.add(box)
+
+ # Creación y configuración de la etiqueta y el botón.
+ label = Gtk.Label('Etiqueta inicial.')
+ label.show()
+ box.pack_start(label, True, True, 0)
+
+ button = Gtk.Button('Cambiar Etiqueta')
+ button.show()
+ box.pack_start(button, False, True, 0)
+
+ # Conecte el callback para el botón.
+ button.connect('clicked', self.__button_clicked_cb)
+
+ # Guarde la etiqueta como una variable de objeto que se pueda acceder
+ # desde el botón de callback.
+ self._label = label
+
+ def __button_clicked_cb(self, button):
+ """Callback para cambiar el texto de la etiqueta cuando se hace clic en
+ el botón."""
+ self._label.set_text('Etiqueta final.')
+
+ def __window_destroy_cb(self, window):
+ """Callback para salir del programa cuando la ventana está cerrada.
+
+ No modifique esto."""
+ Gtk.main_quit()
+
+
+# Ejecute el programa. No modifique esto.
+SimpleWindow().show()
+Gtk.main()
diff --git a/exercises/es/18_gtk-a-actividad.txt b/exercises/es/18_gtk-a-actividad.txt
new file mode 100644
index 0000000..d53410e
--- /dev/null
+++ b/exercises/es/18_gtk-a-actividad.txt
@@ -0,0 +1,5 @@
+Las instrucciones para el ejercicio 18 se encuentran en
+Ejercicio18.activity/ejercicio18.py, que es el único archivo que necesita
+modificar.
+La solución de ejemplo se encuentra en
+Ejercicio18.activity/ejercicio18_solucion.py.
diff --git a/exercises/es/19_traduccion.txt b/exercises/es/19_traduccion.txt
new file mode 100644
index 0000000..980e2f1
--- /dev/null
+++ b/exercises/es/19_traduccion.txt
@@ -0,0 +1,4 @@
+Las instrucciones para el ejercicio 19 se encuentran en
+Ejercicio19.activity/ejercicio19.py. La solución de ejemplo se encuentra en
+Ejercicio19.activity/ejercicio19_solucion.py. No hay ejemplos de archivos de
+solución se proporcionan para los archivos POT y PO.
diff --git a/exercises/es/21_actividad-completo.txt b/exercises/es/21_actividad-completo.txt
new file mode 100644
index 0000000..d1ef2ef
--- /dev/null
+++ b/exercises/es/21_actividad-completo.txt
@@ -0,0 +1,29 @@
+Ejercicio 20
+
+Para este ejercicio final, se debe crear una nueva actividad de Sugar a partir
+de cero. Tiene dos opciones de actividades para crear:
+ A. Un juego de ‘impar hacia fuera’. Debe mostrar cuatro botones en la pantalla,
+ cada uno con una conjugación de un verbo como su texto. Los cuatro
+ conjugaciones deben ser diferentes, y uno debe ser incorrecta. El usuario
+ debe hacer clic en el botón con la conjugación incorrecta. Si lo hacen, su
+ puntuación se incrementa y se muestra otro conjunto de cuatro conjugaciones.
+ Si hacen clic en el botón equivocado, su puntuación no se incrementa y las
+ conjugaciones no cambian. El usuario debe hacer clic en el impar hacia fuera
+ para proceder. La puntuación del usuario se debe mostrar en una etiqueta en
+ la barra de herramientas (pregunte si usted necesita ayuda con esto, o mirar
+ el código en PascalTriangle que hace una cosa similar, poniendo una
+ Gtk.Scale en su barra de herramientas).
+ B. Al igual que en el juego anterior, pero utilizando las igualdades
+ matemáticas en lugar de conjugaciones verbales. El juego debe presentar el
+ usuario con cuatro igualdades (por ejemplo, “5 × 6 + 3 = 33”,
+ “(1 + 4) x 2 = 10”, etc), uno de los cuales debe ser incorrectos. El usuario
+ debe elegir el incorrecto proceder.
+
+Después de haber creado la actividad, probado en la emulación y probado en una
+XO física, usted debe conseguir a alguien más para revisar todo el código y ver
+si se puede encontrar ningún problema con ella. La revisión de código como éste
+siempre es útil, ya que todo programador comete errores (sin importar la
+experiencia que son) y un par de ojos frescos puede detectarlos. Lo ideal sería
+que el código debe ser revisado por una persona que escribió el otro tipo de
+actividad a la que, por lo que tienen que depender de comentarios en el código
+de averiguar cómo las funciones de código. Recuerde comentar bien su código!
diff --git a/exercises/es/Ejercicio18.activity/activity/activity.info b/exercises/es/Ejercicio18.activity/activity/activity.info
new file mode 100644
index 0000000..0e96d5b
--- /dev/null
+++ b/exercises/es/Ejercicio18.activity/activity/activity.info
@@ -0,0 +1,9 @@
+[Activity]
+name = Ejercicio 18
+summary = Ejercicio 18 de Python. No es una actividad real.
+activity_version = 1
+host_version = 1
+bundle_id = hn.educatrachos.ejercicio18
+icon = activity
+exec = sugar-activity ejercicio18.Ejercicio18Actividad
+license = GPLv2+
diff --git a/exercises/es/Ejercicio18.activity/activity/activity.svg b/exercises/es/Ejercicio18.activity/activity/activity.svg
new file mode 100644
index 0000000..580b0e6
--- /dev/null
+++ b/exercises/es/Ejercicio18.activity/activity/activity.svg
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [
+ <!ENTITY stroke_color "#000000">
+ <!ENTITY fill_color "#FFFFFF">
+]>
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg2985"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="New document 2">
+ <defs
+ id="defs2987" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="7"
+ inkscape:cx="24"
+ inkscape:cy="24"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1024"
+ inkscape:window-height="552"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata2990">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="star"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ id="path2999"
+ sodipodi:sides="6"
+ sodipodi:cx="10.142857"
+ sodipodi:cy="10.714286"
+ sodipodi:r1="5.2527933"
+ sodipodi:r2="4.5490522"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.3089969"
+ inkscape:flatsided="true"
+ inkscape:rounded="-0.15648138"
+ inkscape:randomized="0"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ transform="matrix(1.5454814,-0.41411048,0.41411048,1.5454814,3.8875073,0.04153494)" />
+ <g
+ id="g3815"
+ transform="matrix(1.6,0,0,1.6,-13.485714,-7.4857143)">
+ <path
+ transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,6.5725486,11.990245)"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ inkscape:randomized="0"
+ inkscape:rounded="-0.15648138"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.3089969"
+ sodipodi:arg1="0.78539816"
+ sodipodi:r2="4.5490522"
+ sodipodi:r1="5.2527933"
+ sodipodi:cy="10.714286"
+ sodipodi:cx="10.142857"
+ sodipodi:sides="6"
+ id="path2999-6"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ sodipodi:type="star" />
+ <path
+ transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,15.143977,11.990245)"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ inkscape:randomized="0"
+ inkscape:rounded="-0.15648138"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.3089969"
+ sodipodi:arg1="0.78539816"
+ sodipodi:r2="4.5490522"
+ sodipodi:r1="5.2527933"
+ sodipodi:cy="10.714286"
+ sodipodi:cx="10.142857"
+ sodipodi:sides="6"
+ id="path2999-60"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ sodipodi:type="star" />
+ </g>
+ <g
+ id="g3819"
+ transform="matrix(1.6,0,0,1.6,-13.6,-9.0857135)">
+ <path
+ transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,2.2868344,20.20453)"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ inkscape:randomized="0"
+ inkscape:rounded="-0.15648138"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.3089969"
+ sodipodi:arg1="0.78539816"
+ sodipodi:r2="4.5490522"
+ sodipodi:r1="5.2527933"
+ sodipodi:cy="10.714286"
+ sodipodi:cx="10.142857"
+ sodipodi:sides="6"
+ id="path2999-0"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ sodipodi:type="star" />
+ <path
+ transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,10.929691,20.20453)"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ inkscape:randomized="0"
+ inkscape:rounded="-0.15648138"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.3089969"
+ sodipodi:arg1="0.78539816"
+ sodipodi:r2="4.5490522"
+ sodipodi:r1="5.2527933"
+ sodipodi:cy="10.714286"
+ sodipodi:cx="10.142857"
+ sodipodi:sides="6"
+ id="path2999-3"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ sodipodi:type="star" />
+ <path
+ transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,19.572549,20.20453)"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ inkscape:randomized="0"
+ inkscape:rounded="-0.15648138"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.3089969"
+ sodipodi:arg1="0.78539816"
+ sodipodi:r2="4.5490522"
+ sodipodi:r1="5.2527933"
+ sodipodi:cy="10.714286"
+ sodipodi:cx="10.142857"
+ sodipodi:sides="6"
+ id="path2999-1"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ sodipodi:type="star" />
+ </g>
+ </g>
+</svg>
diff --git a/exercises/es/Ejercicio18.activity/ejercicio18.py b/exercises/es/Ejercicio18.activity/ejercicio18.py
new file mode 100644
index 0000000..6282eb7
--- /dev/null
+++ b/exercises/es/Ejercicio18.activity/ejercicio18.py
@@ -0,0 +1,102 @@
+#!/usr/bin/python
+# coding=utf-8
+
+"""Convertir un programa GTK+ simple para ser una actividad de Sugar.
+
+Usted debe convertir la simple programa GTK+ del ejercicio 17 como una
+actividad de Sugar.
+
+Todos los demás archivos de la actividad (activity.info, setup.py, etc.) se han
+previsto ya, simplemente debe modificar el código de este archivo para derivar
+la clase desde sugar3.activity.activity.Activity en lugar de desde Gtk.Window y
+hacer algunos otros cambios.
+
+ 1. Quite la línea “!#/usr/bin/python” desde el principio del archivo. La
+ primera línea del archivo debe ser ahora “# coding=utf-8”.
+ 2. Cambiar el nombre de la clase de “Ejercicio18Actividad”.
+ 3. Agregar un parámetro ‘handle’ al método __init__ y se propagan al
+ constructor principal en la llamada super().
+ 4. Retire el título de la ventana de la llamada a super() de la constructor.
+ 5. Retire la llamada a set_default_size() y el callback para la señal de
+ ‘destroy’ de la ventana.
+ 6. Agregar una barra de herramientas de la actividad (ToolbarBox) y agregue un
+ botón de actividad (ActivityToolbarButton) y un botón de parada
+ (StopButton) a la misma.
+ 7. Cambie el self.add() a self.set_canvas().
+ 8. En un terminal, cambie a este directorio y ejecute ‘./setup.py dev’ para
+ añadir la actividad de Sugar en su ordenador.
+ 9. En una terminal, ejecute ‘sugar-emulator’ y probar la actividad.
+
+Tenga en cuenta que de las declaraciones de ‘import’ necesarios ya se han
+añadido al archivo.
+
+No te olvides de documentar los nuevos métodos que se agregan.
+
+Sugerencia: El código necesario para el paso 6 es:
+ # Crear la caja de herramientas de actividad estándar.
+ toolbar_box = ToolbarBox()
+ self.set_toolbar_box(toolbar_box)
+ toolbar_box.show()
+
+ main_toolbar = toolbar_box.toolbar
+
+ activity_toolbar_button = widgets.ActivityToolbarButton(self)
+ main_toolbar.insert(activity_toolbar_button, 0)
+ activity_toolbar_button.show()
+
+ stop_button = widgets.StopButton(self)
+ stop_button.show()
+ main_toolbar.insert(stop_button, -1)
+"""
+
+from gi.repository import Gtk
+from sugar3.activity import activity, widgets
+from sugar3.graphics.toolbarbox import ToolbarBox
+from sugar3.graphics.toolbutton import ToolButton
+
+
+class SimpleWindow(Gtk.Window):
+ """Una ventana simple que muestra una etiqueta y un botón."""
+ def __init__(self):
+ super(SimpleWindow, self).__init__(title='Ventana Simple')
+
+ # Establecer un tamaño predeterminado de la ventana.
+ self.set_default_size(200, 200)
+
+ # Configurar un callback para cerrar la ventana. No modifique esto.
+ self.connect('destroy', self.__window_destroy_cb)
+
+ # Agregar una caja de la ventana.
+ box = Gtk.Box()
+ box.set_orientation(Gtk.Orientation.VERTICAL)
+ box.set_spacing(8)
+ box.set_border_width(8)
+ box.show()
+ self.add(box)
+
+ # Creación y configuración de la etiqueta y el botón.
+ label = Gtk.Label('Etiqueta inicial.')
+ label.show()
+ box.pack_start(label, True, True, 0)
+
+ button = Gtk.Button('Cambiar Etiqueta')
+ button.show()
+ box.pack_start(button, False, True, 0)
+
+ # Conecte el callback para el botón.
+ button.connect('clicked', self.__button_clicked_cb)
+
+ # Guarde la etiqueta como una variable de objeto que se pueda acceder
+ # desde el callback del botón.
+ self._label = label
+
+ def __button_clicked_cb(self, button):
+ """Callback para cambiar el texto de la etiqueta cuando se hace clic en
+ el botón."""
+ self._label.set_text('Etiqueta final.')
+
+ def __window_destroy_cb(self, window):
+ """Callback para salir del programa cuando la ventana está cerrada.
+
+ No modifique esto."""
+ Gtk.main_quit()
diff --git a/exercises/es/Ejercicio18.activity/ejercicio18_solucion.py b/exercises/es/Ejercicio18.activity/ejercicio18_solucion.py
new file mode 100644
index 0000000..c3d1b08
--- /dev/null
+++ b/exercises/es/Ejercicio18.activity/ejercicio18_solucion.py
@@ -0,0 +1,104 @@
+# coding=utf-8
+
+"""Convertir un programa GTK+ simple para ser una actividad de Sugar.
+
+Usted debe convertir la simple programa GTK+ del ejercicio 17 como una
+actividad de Sugar.
+
+Todos los demás archivos de la actividad (activity.info, setup.py, etc.) se han
+previsto ya, simplemente debe modificar el código de este archivo para derivar
+la clase desde sugar3.activity.activity.Activity en lugar de desde Gtk.Window y
+hacer algunos otros cambios.
+
+ 1. Quite la línea “!#/usr/bin/python” desde el principio del archivo. La
+ primera línea del archivo debe ser ahora “# coding=utf-8”.
+ 2. Cambiar el nombre de la clase de “Ejercicio18Actividad”.
+ 3. Agregar un parámetro ‘handle’ al método __init__ y se propagan al
+ constructor principal en la llamada super().
+ 4. Retire el título de la ventana de la llamada a super() de la constructor.
+ 5. Retire la llamada a set_default_size() y el callback para la señal de
+ ‘destroy’ de la ventana.
+ 6. Agregar una barra de herramientas de la actividad (ToolbarBox) y agregue un
+ botón de actividad (ActivityToolbarButton) y un botón de parada
+ (StopButton) a la misma.
+ 7. Cambie el self.add() a self.set_canvas().
+ 8. En un terminal, cambie a este directorio y ejecute ‘./setup.py dev’ para
+ añadir la actividad de Sugar en su ordenador.
+ 9. En una terminal, ejecute ‘sugar-emulator’ y probar la actividad.
+
+Tenga en cuenta que de las declaraciones de ‘import’ necesarios ya se han
+añadido al archivo.
+
+No te olvides de documentar los nuevos métodos que se agregan.
+
+Sugerencia: El código necesario para el paso 6 es:
+ # Crear la caja de herramientas de actividad estándar.
+ toolbar_box = ToolbarBox()
+ self.set_toolbar_box(toolbar_box)
+ toolbar_box.show()
+
+ main_toolbar = toolbar_box.toolbar
+
+ activity_toolbar_button = widgets.ActivityToolbarButton(self)
+ main_toolbar.insert(activity_toolbar_button, 0)
+ activity_toolbar_button.show()
+
+ stop_button = widgets.StopButton(self)
+ stop_button.show()
+ main_toolbar.insert(stop_button, -1)
+"""
+
+from gi.repository import Gtk
+from sugar3.activity import activity, widgets
+from sugar3.graphics.toolbarbox import ToolbarBox
+from sugar3.graphics.toolbutton import ToolButton
+
+
+class Ejercicio18Actividad(activity.Activity):
+ """Una actividad simple que muestra una etiqueta y un botón."""
+ def __init__(self, handle):
+ super(Ejercicio18Actividad, self).__init__(handle)
+
+ # Crear la caja de herramientas de actividad estándar.
+ toolbar_box = ToolbarBox()
+ self.set_toolbar_box(toolbar_box)
+ toolbar_box.show()
+
+ main_toolbar = toolbar_box.toolbar
+
+ activity_toolbar_button = widgets.ActivityToolbarButton(self)
+ main_toolbar.insert(activity_toolbar_button, 0)
+ activity_toolbar_button.show()
+
+ stop_button = widgets.StopButton(self)
+ stop_button.show()
+ main_toolbar.insert(stop_button, -1)
+
+ # Agregar una caja de la ventana.
+ box = Gtk.Box()
+ box.set_orientation(Gtk.Orientation.VERTICAL)
+ box.set_spacing(8)
+ box.set_border_width(8)
+ box.show()
+ self.set_canvas(box)
+
+ # Creación y configuración de la etiqueta y el botón.
+ label = Gtk.Label('Etiqueta inicial.')
+ label.show()
+ box.pack_start(label, True, True, 0)
+
+ button = Gtk.Button('Cambiar Etiqueta')
+ button.show()
+ box.pack_start(button, False, True, 0)
+
+ # Conecte el callback para el botón.
+ button.connect('clicked', self.__button_clicked_cb)
+
+ # Guarde la etiqueta como una variable de objeto que se pueda acceder
+ # desde el callback para el botón.
+ self._label = label
+
+ def __button_clicked_cb(self, button):
+ """Callback para cambiar el texto de la etiqueta cuando se hace clic en
+ el botón."""
+ self._label.set_text('Etiqueta final.')
diff --git a/exercises/es/Ejercicio18.activity/setup.py b/exercises/es/Ejercicio18.activity/setup.py
new file mode 100755
index 0000000..77fda74
--- /dev/null
+++ b/exercises/es/Ejercicio18.activity/setup.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python
+from sugar.activity import bundlebuilder
+if __name__ == "__main__":
+ bundlebuilder.start()
diff --git a/exercises/es/Ejercicio19.activity/activity/activity.info b/exercises/es/Ejercicio19.activity/activity/activity.info
new file mode 100644
index 0000000..3be89a4
--- /dev/null
+++ b/exercises/es/Ejercicio19.activity/activity/activity.info
@@ -0,0 +1,9 @@
+[Activity]
+name = Ejercicio 19
+summary = Ejercicio 19 de Python. No es una actividad real.
+activity_version = 1
+host_version = 1
+bundle_id = hn.educatrachos.ejercicio19
+icon = activity
+exec = sugar-activity ejercicio19.Ejercicio19Actividad
+license = GPLv2+
diff --git a/exercises/es/Ejercicio19.activity/activity/activity.svg b/exercises/es/Ejercicio19.activity/activity/activity.svg
new file mode 100644
index 0000000..580b0e6
--- /dev/null
+++ b/exercises/es/Ejercicio19.activity/activity/activity.svg
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [
+ <!ENTITY stroke_color "#000000">
+ <!ENTITY fill_color "#FFFFFF">
+]>
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg2985"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="New document 2">
+ <defs
+ id="defs2987" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="7"
+ inkscape:cx="24"
+ inkscape:cy="24"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1024"
+ inkscape:window-height="552"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata2990">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="star"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ id="path2999"
+ sodipodi:sides="6"
+ sodipodi:cx="10.142857"
+ sodipodi:cy="10.714286"
+ sodipodi:r1="5.2527933"
+ sodipodi:r2="4.5490522"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.3089969"
+ inkscape:flatsided="true"
+ inkscape:rounded="-0.15648138"
+ inkscape:randomized="0"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ transform="matrix(1.5454814,-0.41411048,0.41411048,1.5454814,3.8875073,0.04153494)" />
+ <g
+ id="g3815"
+ transform="matrix(1.6,0,0,1.6,-13.485714,-7.4857143)">
+ <path
+ transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,6.5725486,11.990245)"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ inkscape:randomized="0"
+ inkscape:rounded="-0.15648138"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.3089969"
+ sodipodi:arg1="0.78539816"
+ sodipodi:r2="4.5490522"
+ sodipodi:r1="5.2527933"
+ sodipodi:cy="10.714286"
+ sodipodi:cx="10.142857"
+ sodipodi:sides="6"
+ id="path2999-6"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ sodipodi:type="star" />
+ <path
+ transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,15.143977,11.990245)"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ inkscape:randomized="0"
+ inkscape:rounded="-0.15648138"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.3089969"
+ sodipodi:arg1="0.78539816"
+ sodipodi:r2="4.5490522"
+ sodipodi:r1="5.2527933"
+ sodipodi:cy="10.714286"
+ sodipodi:cx="10.142857"
+ sodipodi:sides="6"
+ id="path2999-60"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ sodipodi:type="star" />
+ </g>
+ <g
+ id="g3819"
+ transform="matrix(1.6,0,0,1.6,-13.6,-9.0857135)">
+ <path
+ transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,2.2868344,20.20453)"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ inkscape:randomized="0"
+ inkscape:rounded="-0.15648138"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.3089969"
+ sodipodi:arg1="0.78539816"
+ sodipodi:r2="4.5490522"
+ sodipodi:r1="5.2527933"
+ sodipodi:cy="10.714286"
+ sodipodi:cx="10.142857"
+ sodipodi:sides="6"
+ id="path2999-0"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ sodipodi:type="star" />
+ <path
+ transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,10.929691,20.20453)"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ inkscape:randomized="0"
+ inkscape:rounded="-0.15648138"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.3089969"
+ sodipodi:arg1="0.78539816"
+ sodipodi:r2="4.5490522"
+ sodipodi:r1="5.2527933"
+ sodipodi:cy="10.714286"
+ sodipodi:cx="10.142857"
+ sodipodi:sides="6"
+ id="path2999-3"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ sodipodi:type="star" />
+ <path
+ transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,19.572549,20.20453)"
+ d="m 13.857142,14.428572 c 0.581217,-0.581217 -5.8677649,1.146783 -5.0738083,1.359523 0.7939566,0.21274 -3.9270258,-4.508243 -3.7142858,-3.714286 0.21274,0.793956 1.9407395,-5.6550255 1.3595229,-5.0738089 -0.5812165,0.5812166 5.8677652,-1.1467829 5.0738092,-1.359523 -0.793957,-0.21274 3.927025,4.5082419 3.714285,3.7142858 -0.21274,-0.7939566 -1.940739,5.6550251 -1.359523,5.0738091 z"
+ inkscape:randomized="0"
+ inkscape:rounded="-0.15648138"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.3089969"
+ sodipodi:arg1="0.78539816"
+ sodipodi:r2="4.5490522"
+ sodipodi:r1="5.2527933"
+ sodipodi:cy="10.714286"
+ sodipodi:cx="10.142857"
+ sodipodi:sides="6"
+ id="path2999-1"
+ style="fill:&fill_color;;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1"
+ sodipodi:type="star" />
+ </g>
+ </g>
+</svg>
diff --git a/exercises/es/Ejercicio19.activity/ejercicio19.py b/exercises/es/Ejercicio19.activity/ejercicio19.py
new file mode 100644
index 0000000..5751ef4
--- /dev/null
+++ b/exercises/es/Ejercicio19.activity/ejercicio19.py
@@ -0,0 +1,113 @@
+# coding=utf-8
+
+"""Añadir soporte de internacionalización de una actividad de Sugar.
+
+A continuación se muestra una actividad de Sugar simple que muestra una cadena
+diferente cada vez que se pulsa el botón. Usted debe modificarlo para añadir
+soporte de internacionalización para que su interfaz de usuario se puede ver en
+un idioma diferente.
+
+Todos los demás archivos de la actividad (activity.info, setup.py, etc.) se han
+previsto ya, debe modificar el código de este archivo para añadir soporte de
+internacionalización, generar un archivo POT, y luego traducirlo al español.
+
+Tenga en cuenta que las cadenas originales en todas las actividades siempre
+están en Inglés, por convención.
+
+ 1. Agregue una instrucción ‘import’ para el módulo gettext:
+ from gettext import gettext as _
+ 2. Marcar todos las cadenas pertinentes en el programa como traducible usando
+ la función _().
+ 3. Generar un archivo POT mediante la ejecución de ‘./setup.py genpot’ en un
+ terminal (después de cambiar a este directorio).
+ 4. Copie el archivo generado po/Ejercicio19.pot a po/es.po.
+ 5. De cualquier es.po abierto en un editor de texto, o utilizar una
+ herramienta de traducción como gtranslator y traducir las cadenas de
+ español.
+ 6. Ejecutar ‘./setup.py dev’ ​​para añadir la actividad de Sugar en su
+ ordenador.
+ 7. Ejecutar ‘./setup.py build’ para compilar los archivos en archivos legibles
+ por máquina en el directorio ‘locale’.
+ 8. Ejecutar ‘LANG=es sugar-emulator’ para ejecutar el emulador de Sugar en
+ Español y probar la nueva traducción. Toda la actividad debe aparecer en
+ español.
+
+Nota: No es posible utilizar Pootle para este ejercicio porque es un servicio
+en línea y requeriría el código del ejercicio para publicar en Internet.
+"""
+
+from gi.repository import Gtk
+from sugar3.activity import activity, widgets
+from sugar3.graphics.toolbarbox import ToolbarBox
+
+
+class Ejercicio19Actividad(activity.Activity):
+ """Una ventana simple que muestra una etiqueta y un botón."""
+ def __init__(self, handle):
+ super(Ejercicio19Actividad, self).__init__(handle)
+
+ # Cree la caja de herramientas de la actividad normal.
+ toolbar_box = ToolbarBox()
+ self.set_toolbar_box(toolbar_box)
+ toolbar_box.show()
+
+ main_toolbar = toolbar_box.toolbar
+
+ activity_toolbar_button = widgets.ActivityToolbarButton(self)
+ main_toolbar.insert(activity_toolbar_button, 0)
+ activity_toolbar_button.show()
+
+ stop_button = widgets.StopButton(self)
+ stop_button.show()
+ main_toolbar.insert(stop_button, -1)
+
+ # Agregar una caja de la ventana.
+ box = Gtk.Box()
+ box.set_orientation(Gtk.Orientation.VERTICAL)
+ box.set_spacing(8)
+ box.set_border_width(8)
+ box.show()
+ self.set_canvas(box)
+
+ # Establecer una lista de cadenas de texto que se mostrará en la
+ # etiqueta.
+ self._strings = (
+ 'Cadena inicial.',
+ 'Segunda cadena.',
+ 'Objeto ‘handle’ es ‘%s’.' % handle,
+ 'Otra cadena.',
+ )
+ self._next_string = 0
+
+ # Creación y configuración de la etiqueta y el botón.
+ label = Gtk.Label()
+ label.show()
+ box.pack_start(label, True, True, 0)
+
+ button = Gtk.Button('Cambiar Etiqueta')
+ button.show()
+ box.pack_start(button, False, True, 0)
+
+ # Conecte el callback para el botón.
+ button.connect('clicked', self.__button_clicked_cb)
+
+ # Guarde la etiqueta como una variable de objeto que se pueda acceder
+ # desde el callback para el botón y, a continuación, establecer el
+ # texto inicial de la etiqueta.
+ self._label = label
+ self.__rotate_label_text()
+
+ def __button_clicked_cb(self, button):
+ """Callback para cambiar el texto de la etiqueta cuando se hace clic en
+ el botón."""
+ self.__rotate_label_text()
+
+ def __rotate_label_text(self):
+ """Cambie la etiqueta para mostrar la siguiente cadena en la rotación.
+
+ La operación de módulo se utiliza para envolver alrededor de
+ self._next_string cuando se alcanza el índice final de la matriz
+ self._strings.
+ """
+ self._label.set_text(self._strings[self._next_string])
+ self._next_string = (self._next_string + 1) % len(self._strings)
diff --git a/exercises/es/Ejercicio19.activity/ejercicio19_solucion.py b/exercises/es/Ejercicio19.activity/ejercicio19_solucion.py
new file mode 100644
index 0000000..f08e8e8
--- /dev/null
+++ b/exercises/es/Ejercicio19.activity/ejercicio19_solucion.py
@@ -0,0 +1,114 @@
+# coding=utf-8
+
+"""Añadir soporte de internacionalización de una actividad de Sugar.
+
+A continuación se muestra una actividad de Sugar simple que muestra una cadena
+diferente cada vez que se pulsa el botón. Usted debe modificarlo para añadir
+soporte de internacionalización para que su interfaz de usuario se puede ver en
+un idioma diferente.
+
+Todos los demás archivos de la actividad (activity.info, setup.py, etc.) se han
+previsto ya, debe modificar el código de este archivo para añadir soporte de
+internacionalización, generar un archivo POT, y luego traducirlo al español.
+
+Tenga en cuenta que las cadenas originales en todas las actividades siempre
+están en Inglés, por convención.
+
+ 1. Agregue una instrucción ‘import’ para el módulo gettext:
+ from gettext import gettext as _
+ 2. Marcar todos las cadenas pertinentes en el programa como traducible usando
+ la función _().
+ 3. Generar un archivo POT mediante la ejecución de ‘./setup.py genpot’ en un
+ terminal (después de cambiar a este directorio).
+ 4. Copie el archivo generado po/Ejercicio19.pot a po/es.po.
+ 5. De cualquier es.po abierto en un editor de texto, o utilizar una
+ herramienta de traducción como gtranslator y traducir las cadenas de
+ español.
+ 6. Ejecutar ‘./setup.py dev’ ​​para añadir la actividad de Sugar en su
+ ordenador.
+ 7. Ejecutar ‘./setup.py build’ para compilar los archivos en archivos legibles
+ por máquina en el directorio ‘locale’.
+ 8. Ejecutar ‘LANG=es sugar-emulator’ para ejecutar el emulador de Sugar en
+ Español y probar la nueva traducción. Toda la actividad debe aparecer en
+ español.
+
+Nota: No es posible utilizar Pootle para este ejercicio porque es un servicio
+en línea y requeriría el código del ejercicio para publicar en Internet.
+"""
+
+from gi.repository import Gtk
+from sugar3.activity import activity, widgets
+from sugar3.graphics.toolbarbox import ToolbarBox
+from gettext import gettext as _
+
+
+class Ejercicio19Actividad(activity.Activity):
+ """Una ventana simple que muestra una etiqueta y un botón."""
+ def __init__(self, handle):
+ super(Ejercicio19Actividad, self).__init__(handle)
+
+ # Cree la caja de herramientas de la actividad normal.
+ toolbar_box = ToolbarBox()
+ self.set_toolbar_box(toolbar_box)
+ toolbar_box.show()
+
+ main_toolbar = toolbar_box.toolbar
+
+ activity_toolbar_button = widgets.ActivityToolbarButton(self)
+ main_toolbar.insert(activity_toolbar_button, 0)
+ activity_toolbar_button.show()
+
+ stop_button = widgets.StopButton(self)
+ stop_button.show()
+ main_toolbar.insert(stop_button, -1)
+
+ # Agregar una caja de la ventana.
+ box = Gtk.Box()
+ box.set_orientation(Gtk.Orientation.VERTICAL)
+ box.set_spacing(8)
+ box.set_border_width(8)
+ box.show()
+ self.set_canvas(box)
+
+ # Establecer una lista de cadenas de texto que se mostrará en la
+ # etiqueta.
+ self._strings = (
+ _('Cadena inicial.'),
+ _('Segunda cadena.'),
+ _('Objeto ‘handle’ es ‘%s’.') % handle,
+ _('Otra cadena.'),
+ )
+ self._next_string = 0
+
+ # Creación y configuración de la etiqueta y el botón.
+ label = Gtk.Label()
+ label.show()
+ box.pack_start(label, True, True, 0)
+
+ button = Gtk.Button(_('Cambiar Etiqueta'))
+ button.show()
+ box.pack_start(button, False, True, 0)
+
+ # Conecte el callback para el botón.
+ button.connect('clicked', self.__button_clicked_cb)
+
+ # Guarde la etiqueta como una variable de objeto que se pueda acceder
+ # desde el callback para el botón y, a continuación, establecer el
+ # texto inicial de la etiqueta.
+ self._label = label
+ self.__rotate_label_text()
+
+ def __button_clicked_cb(self, button):
+ """Callback para cambiar el texto de la etiqueta cuando se hace clic en
+ el botón."""
+ self.__rotate_label_text()
+
+ def __rotate_label_text(self):
+ """Cambie la etiqueta para mostrar la siguiente cadena en la rotación.
+
+ La operación de módulo se utiliza para envolver alrededor de
+ self._next_string cuando se alcanza el índice final de la matriz
+ self._strings.
+ """
+ self._label.set_text(self._strings[self._next_string])
+ self._next_string = (self._next_string + 1) % len(self._strings)
diff --git a/exercises/es/Ejercicio19.activity/setup.py b/exercises/es/Ejercicio19.activity/setup.py
new file mode 100755
index 0000000..77fda74
--- /dev/null
+++ b/exercises/es/Ejercicio19.activity/setup.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python
+from sugar.activity import bundlebuilder
+if __name__ == "__main__":
+ bundlebuilder.start()
diff --git a/exercises/es/Ejercicio20.activity/.gitignore b/exercises/es/Ejercicio20.activity/.gitignore
new file mode 100644
index 0000000..6a592c9
--- /dev/null
+++ b/exercises/es/Ejercicio20.activity/.gitignore
@@ -0,0 +1,3 @@
+*.pyc
+dist/
+locale/
diff --git a/exercises/es/Ejercicio20.activity/activity/activity.info b/exercises/es/Ejercicio20.activity/activity/activity.info
new file mode 100644
index 0000000..0bc7159
--- /dev/null
+++ b/exercises/es/Ejercicio20.activity/activity/activity.info
@@ -0,0 +1,9 @@
+[Activity]
+name = Ejercicio 20
+summary = Ejercicio 20 de Python. No es una actividad real.
+activity_version = 1
+host_version = 1
+bundle_id = hn.educatrachos.ejercicio20
+icon = activity
+exec = sugar-activity ejercicio20.Ejercicio20Actividad
+license = GPLv2+
diff --git a/exercises/es/Ejercicio20.activity/ejercicio20.py b/exercises/es/Ejercicio20.activity/ejercicio20.py
new file mode 100644
index 0000000..025e420
--- /dev/null
+++ b/exercises/es/Ejercicio20.activity/ejercicio20.py
@@ -0,0 +1,78 @@
+# coding=utf-8
+
+"""Empaquetar una actividad de Sugar para producir un paquete.
+
+A continuación se muestra una actividad de Sugar simple que muestra una imagen
+estática. Es muy aburrido, pero no necesita cambiar. En este ejercicio, debe
+agregar los archivos correspondientes a git y luego construir un paquete para
+la actividad e instalarlo en una computadora portátil XO físico.
+
+Antes de empaqueto de la actividad, un icono tiene que ser creado.
+
+ 1. Abra el Inkscape y crear un nuevo icono de 48×48 píxeles (plantilla
+ ‘icon_48x48’).
+ 2. Dibuja el icono, con un solo color de trazo y un solo color de fondo.
+ Guárdelo como activity/activity.svg.
+ 3. Abra el archivo SVG creado con un editor de texto y cambie los colores de
+ trazo como se describe en la sección ‘Crear un ícono’ aquí:
+ http://en.flossmanuals.net/como-hacer-una-actividad-sugar/empaquetar-tu-actividad-ac-100/
+ 4. Ejecute los siguientes comandos en un terminal abierto en la directorio
+ Ejercicio20.activity/. Se agregarán los archivos pertinentes a git:
+ git init
+ git status
+ git add .gitignore ejercicio20.py setup.py images/logonew2.png
+ git add activity/activity.info
+ git add activity/activity.svg
+ git status
+ git commit
+ Crean un nuevo repositorio git en el directorio actual, comproban su
+ estado, agregan los archivos necesarios en el repositorio, comproban su
+ estado nuevo para asegurarse de que no cometemos cualquier cosa que no
+ queremos, y luego confirman los archivos nuevos y los cambios en el
+ repositorio.
+
+ El .gitignore es un archivo especial que enumera los archivos que git no
+ debe permitir que usted agregue al repositorio, y que se oculta a la salida
+ del `git status`.
+ 5. Ejecutar ‘./setup.py dist_xo’ para construir un paquete XO.
+ 6. Copie el archivo dist/Ejercicio20-1.xo en una memoria USB e instalarlo en
+ una computadora portátil XO físico.
+"""
+
+from gi.repository import Gtk
+from sugar3.activity import activity, widgets
+from sugar3.graphics.toolbarbox import ToolbarBox
+import os
+
+
+class Ejercicio20Actividad(activity.Activity):
+ """Una simple ventana que muestra una imagen estática."""
+ def __init__(self, handle):
+ super(Ejercicio20Actividad, self).__init__(handle)
+
+ # Cree la caja de herramientas de la actividad normal.
+ toolbar_box = ToolbarBox()
+ self.set_toolbar_box(toolbar_box)
+ toolbar_box.show()
+
+ main_toolbar = toolbar_box.toolbar
+
+ activity_toolbar_button = widgets.ActivityToolbarButton(self)
+ main_toolbar.insert(activity_toolbar_button, 0)
+ activity_toolbar_button.show()
+
+ stop_button = widgets.StopButton(self)
+ stop_button.show()
+ main_toolbar.insert(stop_button, -1)
+
+ # Añadir una imagen a la ventana.
+ box = Gtk.Box()
+ box.show()
+ self.set_canvas(box)
+
+ image = Gtk.Image()
+ filename = os.path.join(os.path.dirname(__file__),
+ 'images', 'logonew2.png')
+ image.set_from_file(filename)
+ image.show()
+ box.pack_start(image, True, True, 8)
diff --git a/exercises/es/Ejercicio20.activity/images/logonew2.png b/exercises/es/Ejercicio20.activity/images/logonew2.png
new file mode 100644
index 0000000..d523b0b
--- /dev/null
+++ b/exercises/es/Ejercicio20.activity/images/logonew2.png
Binary files differ
diff --git a/exercises/es/Ejercicio20.activity/setup.py b/exercises/es/Ejercicio20.activity/setup.py
new file mode 100755
index 0000000..77fda74
--- /dev/null
+++ b/exercises/es/Ejercicio20.activity/setup.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python
+from sugar.activity import bundlebuilder
+if __name__ == "__main__":
+ bundlebuilder.start()