diff --git a/2018/index.html b/2018/index.html index 988745160..f98548298 100644 --- a/2018/index.html +++ b/2018/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/Admin/dominios/index.html b/Admin/dominios/index.html index aa7d3004d..c14e1fb1c 100644 --- a/Admin/dominios/index.html +++ b/Admin/dominios/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/AlejandroJCura/classdeco/index.html b/AlejandroJCura/classdeco/index.html index d8935044d..380fcbcbb 100644 --- a/AlejandroJCura/classdeco/index.html +++ b/AlejandroJCura/classdeco/index.html @@ -33,7 +33,7 @@ prev_new = cls.__new__ "> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + @@ -91,31 +91,31 @@

Un Ejemplo De Class Decorators (Python 3)

-
class LimitExceededException(Exception):
-    pass
-
-class limit_instances:
-    def __init__(self, limit):
-        self.limit = limit
-
-    def __call__(self, cls):
-        prev_new = cls.__new__
-        cls.__num = 0
-        def __new__(cls, *a, **kw):
-            cls.__num += 1
-            if cls.__num > self.limit:
-                raise LimitExceededException()
-            return prev_new(cls, *a, **kw)
-        cls.__new__ = __new__
-        return cls
-
-@limit_instances(5)
-class C:
-    pass
-
-for n in range(10):
-    c=C()
-    print(c)
+    
class LimitExceededException(Exception):
+    pass
+
+class limit_instances:
+    def __init__(self, limit):
+        self.limit = limit
+
+    def __call__(self, cls):
+        prev_new = cls.__new__
+        cls.__num = 0
+        def __new__(cls, *a, **kw):
+            cls.__num += 1
+            if cls.__num > self.limit:
+                raise LimitExceededException()
+            return prev_new(cls, *a, **kw)
+        cls.__new__ = __new__
+        return cls
+
+@limit_instances(5)
+class C:
+    pass
+
+for n in range(10):
+    c=C()
+    print(c)
 
diff --git a/AlejandroJCura/compactoexquisito/index.html b/AlejandroJCura/compactoexquisito/index.html index 0372ae590..107150c4b 100644 --- a/AlejandroJCura/compactoexquisito/index.html +++ b/AlejandroJCura/compactoexquisito/index.html @@ -27,7 +27,7 @@ La ausencia de melodías en este disco parece algo planificado por Mansoor para volver a sorprendernos. Y es que el vigesimosegundo disco editado en 2009 de este multifacético "> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/AlejandroJCura/graficos/index.html b/AlejandroJCura/graficos/index.html index ed72ddc05..0a7419264 100644 --- a/AlejandroJCura/graficos/index.html +++ b/AlejandroJCura/graficos/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/AsociacionCivil/Autoridades/candidatos/index.html b/AsociacionCivil/Autoridades/candidatos/index.html index 061958105..eb61fcdaf 100644 --- a/AsociacionCivil/Autoridades/candidatos/index.html +++ b/AsociacionCivil/Autoridades/candidatos/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/AsociacionCivil/Minutas/20160412/index.html b/AsociacionCivil/Minutas/20160412/index.html index bff834bef..f3e757e4b 100644 --- a/AsociacionCivil/Minutas/20160412/index.html +++ b/AsociacionCivil/Minutas/20160412/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/AsociacionCivil/Minutas/20160428/index.html b/AsociacionCivil/Minutas/20160428/index.html index 3423fa161..0b8ddc161 100644 --- a/AsociacionCivil/Minutas/20160428/index.html +++ b/AsociacionCivil/Minutas/20160428/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/AsociacionCivil/Minutas/20160510/index.html b/AsociacionCivil/Minutas/20160510/index.html index 199a7237b..14e4eaa2f 100644 --- a/AsociacionCivil/Minutas/20160510/index.html +++ b/AsociacionCivil/Minutas/20160510/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/AsociacionCivil/Minutas/20160526/index.html b/AsociacionCivil/Minutas/20160526/index.html index 57379a5a1..78631c3e5 100644 --- a/AsociacionCivil/Minutas/20160526/index.html +++ b/AsociacionCivil/Minutas/20160526/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/AsociacionCivil/Minutas/20160614/index.html b/AsociacionCivil/Minutas/20160614/index.html index a8da44fb6..6dc6f92db 100644 --- a/AsociacionCivil/Minutas/20160614/index.html +++ b/AsociacionCivil/Minutas/20160614/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/AsociacionCivil/Minutas/20160630/index.html b/AsociacionCivil/Minutas/20160630/index.html index 1ef445d46..5276ac039 100644 --- a/AsociacionCivil/Minutas/20160630/index.html +++ b/AsociacionCivil/Minutas/20160630/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/AsociacionCivil/Minutas/20160712/index.html b/AsociacionCivil/Minutas/20160712/index.html index 671900420..1668a5794 100644 --- a/AsociacionCivil/Minutas/20160712/index.html +++ b/AsociacionCivil/Minutas/20160712/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/AsociacionCivil/Minutas/20160921/index.html b/AsociacionCivil/Minutas/20160921/index.html index d30e5e832..25668cf76 100644 --- a/AsociacionCivil/Minutas/20160921/index.html +++ b/AsociacionCivil/Minutas/20160921/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/AsociacionCivil/autoridades/index.html b/AsociacionCivil/autoridades/index.html index 40a1ca8be..c4e7764d2 100644 --- a/AsociacionCivil/autoridades/index.html +++ b/AsociacionCivil/autoridades/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/AsociacionCivil/encuesta/index.html b/AsociacionCivil/encuesta/index.html index e687cbedb..e6a53a021 100644 --- a/AsociacionCivil/encuesta/index.html +++ b/AsociacionCivil/encuesta/index.html @@ -27,7 +27,7 @@ Promedio aproximado de Cuota Social: $ 70 Personas interesadas en vot"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/AsociacionCivil/minutas/index.html b/AsociacionCivil/minutas/index.html index 61b272e85..29d79e49b 100644 --- a/AsociacionCivil/minutas/index.html +++ b/AsociacionCivil/minutas/index.html @@ -31,7 +31,7 @@ 2016-07-12 por IRC 2016-09-11 por IRC y Hangout"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/AsociacionCivil/mision/index.html b/AsociacionCivil/mision/index.html index 86348f11c..b0ce95e0c 100644 --- a/AsociacionCivil/mision/index.html +++ b/AsociacionCivil/mision/index.html @@ -26,7 +26,7 @@ Sin fines de lucro la realización de todo tipo de actividades de fomento, promoción, protección, difusión y desarrollo del lenguaje de programación "> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/Bandera/cambiadas/index.html b/Bandera/cambiadas/index.html index f4dea4753..07103f191 100644 --- a/Bandera/cambiadas/index.html +++ b/Bandera/cambiadas/index.html @@ -37,7 +37,7 @@ * El usuario pidio cambiar "> - + Ir al contenido principal @@ -71,12 +71,12 @@ - + diff --git a/Bandera/descalificadas/index.html b/Bandera/descalificadas/index.html index 3d0f9bde7..08303e4ce 100644 --- a/Bandera/descalificadas/index.html +++ b/Bandera/descalificadas/index.html @@ -34,7 +34,7 @@ Esta bandera debió ser descalificada porque no cumple con las reglas del concurso. En particular, el "> - + Ir al contenido principal @@ -68,12 +68,12 @@ - + diff --git a/Bandera/detallevotos/index.html b/Bandera/detallevotos/index.html index 200ff2684..e9c8c4297 100644 --- a/Bandera/detallevotos/index.html +++ b/Bandera/detallevotos/index.html @@ -41,7 +41,7 @@ Pablo2: 2 Pa"> - + Ir al contenido principal @@ -75,12 +75,12 @@ - + diff --git a/Bandera/fotos/index.html b/Bandera/fotos/index.html index 4ee4a077d..ee2071625 100644 --- a/Bandera/fotos/index.html +++ b/Bandera/fotos/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Bandera/propuestas/index.html b/Bandera/propuestas/index.html index 96e3cf002..91a7bfbbf 100644 --- a/Bandera/propuestas/index.html +++ b/Bandera/propuestas/index.html @@ -36,7 +36,7 @@ SVG: http://alecu.com.ar/band"> - + Ir al contenido principal @@ -70,12 +70,12 @@ - + diff --git a/Bandera/resultados/index.html b/Bandera/resultados/index.html index 44aef1fb6..2ab5e9f2c 100644 --- a/Bandera/resultados/index.html +++ b/Bandera/resultados/index.html @@ -42,7 +42,7 @@ Pablo4 {{http://alecu.com.ar/banderas/pabl"> - + Ir al contenido principal @@ -76,12 +76,12 @@ - + diff --git a/Bandera/variaciones/index.html b/Bandera/variaciones/index.html index a4461077e..6ba14a639 100644 --- a/Bandera/variaciones/index.html +++ b/Bandera/variaciones/index.html @@ -31,7 +31,7 @@ Con PyAr en versalitas"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/CNAME b/CNAME deleted file mode 100644 index 389d86ac8..000000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -wiki.python.org.ar \ No newline at end of file diff --git a/CambiosRecientes/test/index.html b/CambiosRecientes/test/index.html index f25c0742a..56eb53122 100644 --- a/CambiosRecientes/test/index.html +++ b/CambiosRecientes/test/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/CharlasAbiertas2010/django/index.html b/CharlasAbiertas2010/django/index.html index 62e9d8c54..4b7e34c65 100644 --- a/CharlasAbiertas2010/django/index.html +++ b/CharlasAbiertas2010/django/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/CharlasAbiertas2010/foobar/index.html b/CharlasAbiertas2010/foobar/index.html index a44c1ad56..80c6f839e 100644 --- a/CharlasAbiertas2010/foobar/index.html +++ b/CharlasAbiertas2010/foobar/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/CharlasAbiertas2010/introduccionalaprogramacion/index.html b/CharlasAbiertas2010/introduccionalaprogramacion/index.html index 688a44928..c06b8034c 100644 --- a/CharlasAbiertas2010/introduccionalaprogramacion/index.html +++ b/CharlasAbiertas2010/introduccionalaprogramacion/index.html @@ -26,7 +26,7 @@ básicos de este arte de manera que dicha persona pueda, comprendiendo las bases de la disciplina, tene"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/CharlasAbiertas2010/introduccionaldesarrollowebi/index.html b/CharlasAbiertas2010/introduccionaldesarrollowebi/index.html index 21c3880a8..7e3285d16 100644 --- a/CharlasAbiertas2010/introduccionaldesarrollowebi/index.html +++ b/CharlasAbiertas2010/introduccionaldesarrollowebi/index.html @@ -26,7 +26,7 @@ principales del mundo web (HTML, HTTP, MVC, etc.), presentando la herramienta de desarrollo !Web2Py, de mu"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/CharlasAbiertas2010/introduccionaldesarrollowebii/index.html b/CharlasAbiertas2010/introduccionaldesarrollowebii/index.html index 8859b1a7b..0831df334 100644 --- a/CharlasAbiertas2010/introduccionaldesarrollowebii/index.html +++ b/CharlasAbiertas2010/introduccionaldesarrollowebii/index.html @@ -26,7 +26,7 @@ principales del mundo web (HTML, HTTP, MVC, etc.), presentando la herramienta de desarrollo Web2Py, de muy"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/CharlasAbiertas2010/introduccionaplone/index.html b/CharlasAbiertas2010/introduccionaplone/index.html index cfcbbabfc..1b959b7ab 100644 --- a/CharlasAbiertas2010/introduccionaplone/index.html +++ b/CharlasAbiertas2010/introduccionaplone/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/CharlasAbiertas2010/introduccionapython/index.html b/CharlasAbiertas2010/introduccionapython/index.html index 90df65143..af2e3dd93 100644 --- a/CharlasAbiertas2010/introduccionapython/index.html +++ b/CharlasAbiertas2010/introduccionapython/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/CharlasAbiertas2010/introducciongui_i/index.html b/CharlasAbiertas2010/introducciongui_i/index.html index 8e84d1668..ad64e4a13 100644 --- a/CharlasAbiertas2010/introducciongui_i/index.html +++ b/CharlasAbiertas2010/introducciongui_i/index.html @@ -27,7 +27,7 @@ Dis"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/CharlasAbiertas2010/introducciongui_ii/index.html b/CharlasAbiertas2010/introducciongui_ii/index.html index c9f6831d1..128c2cdea 100644 --- a/CharlasAbiertas2010/introducciongui_ii/index.html +++ b/CharlasAbiertas2010/introducciongui_ii/index.html @@ -27,7 +27,7 @@ Dis"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/CharlasAbiertas2010/optimizandopython/index.html b/CharlasAbiertas2010/optimizandopython/index.html index 02aa54b17..c8497adb4 100644 --- a/CharlasAbiertas2010/optimizandopython/index.html +++ b/CharlasAbiertas2010/optimizandopython/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/CharlasAbiertas2010/pyqt/index.html b/CharlasAbiertas2010/pyqt/index.html index a06375638..2ffa7a94c 100644 --- a/CharlasAbiertas2010/pyqt/index.html +++ b/CharlasAbiertas2010/pyqt/index.html @@ -26,7 +26,7 @@ Disertante: Roberto Alsina Esta charla fue cancelad"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/CharlasAbiertas2010/python3000/index.html b/CharlasAbiertas2010/python3000/index.html index 18857f242..cce199d27 100644 --- a/CharlasAbiertas2010/python3000/index.html +++ b/CharlasAbiertas2010/python3000/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/CharlasAbiertas2010/tallerjuegos/index.html b/CharlasAbiertas2010/tallerjuegos/index.html index abc4788fa..3f7cac432 100644 --- a/CharlasAbiertas2010/tallerjuegos/index.html +++ b/CharlasAbiertas2010/tallerjuegos/index.html @@ -28,7 +28,7 @@ Día 9: Sábado 20 de Noviembre 10:30 a 15 ho"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/CharlasAbiertas2010/twisted/index.html b/CharlasAbiertas2010/twisted/index.html index b190943c2..8bc9ec62f 100644 --- a/CharlasAbiertas2010/twisted/index.html +++ b/CharlasAbiertas2010/twisted/index.html @@ -27,7 +27,7 @@ Disertante: Lucio Torre Día 8: Sáb"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/CharlasAbiertas2010/wxpython/index.html b/CharlasAbiertas2010/wxpython/index.html index fabc53d94..479c8b1a8 100644 --- a/CharlasAbiertas2010/wxpython/index.html +++ b/CharlasAbiertas2010/wxpython/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/Conferencias/pyconar2014/index.html b/Conferencias/pyconar2014/index.html index 3daaebb5a..2e7221d7d 100644 --- a/Conferencias/pyconar2014/index.html +++ b/Conferencias/pyconar2014/index.html @@ -26,7 +26,7 @@ PyConAr2014 (dejo este mensaje para quien llegue por link incorrecto)"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/Donaciones/lala/index.html b/Donaciones/lala/index.html index 17a31f5a8..cd45fcccd 100644 --- a/Donaciones/lala/index.html +++ b/Donaciones/lala/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/GSoC/2019/index.html b/GSoC/2019/index.html index f7168e8ca..4e72ae642 100644 --- a/GSoC/2019/index.html +++ b/GSoC/2019/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/GSoC/2022/index.html b/GSoC/2022/index.html index 16e13e0b3..c89f7e38d 100644 --- a/GSoC/2022/index.html +++ b/GSoC/2022/index.html @@ -27,7 +27,7 @@ The following are the Python Argentina projects that could participate in Google Summer of Code 2022 (under the PSF org). Ideas are tentative, please engage with the community"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/GSoC/2023/index.html b/GSoC/2023/index.html index 33c5194d2..aa1184c29 100644 --- a/GSoC/2023/index.html +++ b/GSoC/2023/index.html @@ -27,7 +27,7 @@ The following are the Python Argentina projects that could participate in Google Summer of Code 2023 (under the PSF org). Ideas are tentative, please engage with the community"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/GSoC/2024/index.html b/GSoC/2024/index.html index f3cf7fa33..53e90f58d 100644 --- a/GSoC/2024/index.html +++ b/GSoC/2024/index.html @@ -27,7 +27,7 @@ The following are the Python Argentina projects that could participate in Google Summer of Code 2024 (under the PSF org). Ideas are tentative, please engage with the community"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/GSoC/ideas/index.html b/GSoC/ideas/index.html index e0057f19f..e7420c9fc 100644 --- a/GSoC/ideas/index.html +++ b/GSoC/ideas/index.html @@ -29,7 +29,7 @@ 2021 (archivado) 2022 <-- Programa Actual"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/Gui/Gtk/vbox/index.html b/Gui/Gtk/vbox/index.html index b02d34baa..2f2452295 100644 --- a/Gui/Gtk/vbox/index.html +++ b/Gui/Gtk/vbox/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/HGTTP/contabilidad/index.html b/HGTTP/contabilidad/index.html index b59b96e0f..47b5206b4 100644 --- a/HGTTP/contabilidad/index.html +++ b/HGTTP/contabilidad/index.html @@ -27,7 +27,7 @@ Previsibilidad Económica: Para esta área es importante saber algunos datos: Elab"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/HGTTP/disertantes/index.html b/HGTTP/disertantes/index.html index be02b1c01..48bbc3e2d 100644 --- a/HGTTP/disertantes/index.html +++ b/HGTTP/disertantes/index.html @@ -26,7 +26,7 @@ Keynotes: Invitados por la organización a hablar, esto es la cereza del postre de las charlas, la parte mas show del evento. Algunos tips a tener en cue"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/HGTTP/equipo/index.html b/HGTTP/equipo/index.html index 8afbbe41b..82825a4ab 100644 --- a/HGTTP/equipo/index.html +++ b/HGTTP/equipo/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/HGTTP/informacion/index.html b/HGTTP/informacion/index.html index 970928e95..cb4d53a2e 100644 --- a/HGTTP/informacion/index.html +++ b/HGTTP/informacion/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/HGTTP/logistica/index.html b/HGTTP/logistica/index.html index f22c84a60..8271f9f4c 100644 --- a/HGTTP/logistica/index.html +++ b/HGTTP/logistica/index.html @@ -29,7 +29,7 @@ Carteles en todos los lugares que vaya a haber o pasar gente con indicaciones de como llegar a los lugares asignados. Carte"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/HGTTP/logistica_pre/index.html b/HGTTP/logistica_pre/index.html index 0a2f36870..0982db946 100644 --- a/HGTTP/logistica_pre/index.html +++ b/HGTTP/logistica_pre/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/HGTTP/lugar/index.html b/HGTTP/lugar/index.html index 43438bcce..3cb3f4dd2 100644 --- a/HGTTP/lugar/index.html +++ b/HGTTP/lugar/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/HGTTP/marketing/index.html b/HGTTP/marketing/index.html index 32d8a22fa..c1bcd276e 100644 --- a/HGTTP/marketing/index.html +++ b/HGTTP/marketing/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/HGTTP/sponsoring/index.html b/HGTTP/sponsoring/index.html index ff23efda8..810b02d22 100644 --- a/HGTTP/sponsoring/index.html +++ b/HGTTP/sponsoring/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/ListaDeCorreo/bar/index.html b/ListaDeCorreo/bar/index.html index 132d977d6..ef502a231 100644 --- a/ListaDeCorreo/bar/index.html +++ b/ListaDeCorreo/bar/index.html @@ -26,7 +26,7 @@ no están relacionados con la promoción, difusión y temas técnicos del lenguaje de programación Python, podés hacerlo suscribiéndote a: ht"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/ListaDeCorreo/migracion/index.html b/ListaDeCorreo/migracion/index.html index eae4c9946..026fc14c9 100644 --- a/ListaDeCorreo/migracion/index.html +++ b/ListaDeCorreo/migracion/index.html @@ -27,7 +27,7 @@ 1. empezar a probar desde todos los webmail"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/LlamadoasedePyconar2012/pyconar2012bsas/index.html b/LlamadoasedePyconar2012/pyconar2012bsas/index.html index 82cdf972d..879956d51 100644 --- a/LlamadoasedePyconar2012/pyconar2012bsas/index.html +++ b/LlamadoasedePyconar2012/pyconar2012bsas/index.html @@ -27,7 +27,7 @@ Fecha: 12 al 17 de Noviembre de 2012 (--17 al 22 de Septiembre de 2012 o 1 al 6 de Octubre de 2012--) Lugar: UNQUI (preconfirmada, ver: nota); UPE y UNGS (interesadas); UTN FRBA ("> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git "a/ManuelQui\303\261ones/PruebaCal/2010-09-04/index.html" "b/ManuelQui\303\261ones/PruebaCal/2010-09-04/index.html" index 626b16691..58b36a27b 100644 --- "a/ManuelQui\303\261ones/PruebaCal/2010-09-04/index.html" +++ "b/ManuelQui\303\261ones/PruebaCal/2010-09-04/index.html" @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git "a/ManuelQui\303\261ones/PruebaCal/2010-10-15/index.html" "b/ManuelQui\303\261ones/PruebaCal/2010-10-15/index.html" index cf06e468c..b523dd917 100644 --- "a/ManuelQui\303\261ones/PruebaCal/2010-10-15/index.html" +++ "b/ManuelQui\303\261ones/PruebaCal/2010-10-15/index.html" @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git "a/ManuelQui\303\261ones/PruebaCal/2010-10-16/index.html" "b/ManuelQui\303\261ones/PruebaCal/2010-10-16/index.html" index e9b0056c5..adb704fa9 100644 --- "a/ManuelQui\303\261ones/PruebaCal/2010-10-16/index.html" +++ "b/ManuelQui\303\261ones/PruebaCal/2010-10-16/index.html" @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git "a/ManuelQui\303\261ones/PruebaCal/pycon2010/index.html" "b/ManuelQui\303\261ones/PruebaCal/pycon2010/index.html" index 0bdc9b2dc..45f865716 100644 --- "a/ManuelQui\303\261ones/PruebaCal/pycon2010/index.html" +++ "b/ManuelQui\303\261ones/PruebaCal/pycon2010/index.html" @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git "a/ManuelQui\303\261ones/pruebacal/index.html" "b/ManuelQui\303\261ones/pruebacal/index.html" index 50ea91a26..771cdcf9f 100644 --- "a/ManuelQui\303\261ones/pruebacal/index.html" +++ "b/ManuelQui\303\261ones/pruebacal/index.html" @@ -26,7 +26,7 @@ ||||||||<bgcolor="#ffffcc"> '''2010''' || || <<MonthCalendar(,2010,7,,,1)>> || <<MonthCalendar(,2010,8,,,1)>> |"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/MarianoGuerra/holamundo/index.html b/MarianoGuerra/holamundo/index.html index 02adb833c..bdb1c3366 100644 --- a/MarianoGuerra/holamundo/index.html +++ b/MarianoGuerra/holamundo/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + @@ -82,7 +82,7 @@

Marianoguerra/holamundo

-
print "hola mundo!"
+    
print "hola mundo!"
 
diff --git a/Material/agua/index.html b/Material/agua/index.html index 66e77436f..255bb2f48 100644 --- a/Material/agua/index.html +++ b/Material/agua/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/MatiasGieco/prueba01/index.html b/MatiasGieco/prueba01/index.html index bf812a2fc..819403f2e 100644 --- a/MatiasGieco/prueba01/index.html +++ b/MatiasGieco/prueba01/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + @@ -82,7 +82,7 @@

Prueba01

-
print "hola mundo"
+    
print "hola mundo"
 
diff --git a/Noticias/2004/index.html b/Noticias/2004/index.html index 2426dd1c6..958b37955 100644 --- a/Noticias/2004/index.html +++ b/Noticias/2004/index.html @@ -30,7 +30,7 @@ La última versión de Python ya está en la calle. Ya está disponible el módulo decimal para Python 2.3."> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/Noticias/2005/index.html b/Noticias/2005/index.html index 5a24c600c..34a90b36c 100644 --- a/Noticias/2005/index.html +++ b/Noticias/2005/index.html @@ -42,7 +42,7 @@ 11/04/200"> - + Ir al contenido principal @@ -76,12 +76,12 @@ - + diff --git a/Noticias/2006/index.html b/Noticias/2006/index.html index c958adb30..fff28385d 100644 --- a/Noticias/2006/index.html +++ b/Noticias/2006/index.html @@ -30,7 +30,7 @@ 10/11/20"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/Noticias/2007/index.html b/Noticias/2007/index.html index df1cf55f8..bb7309273 100644 --- a/Noticias/2007/index.html +++ b/Noticias/2007/index.html @@ -26,7 +26,7 @@ Los días 6 y 7 de diciembre próximo se estará realizando la 3era edición del evento WhyFLOSS Conference en las instalaciones del Instituto Tecnológico de Buenos Aires (ITBA) de Puerto Made"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/Noticias/2008/index.html b/Noticias/2008/index.html index 195cd40ca..e62cc59ed 100644 --- a/Noticias/2008/index.html +++ b/Noticias/2008/index.html @@ -26,7 +26,7 @@ Vamos a participar de Fábrica de Fallas, el 1er festival de Cultura Libre y Copyleft, que tendrá lugar el 15 y 16 de noviembre de 14 a 21 hs en FM La Tribu, Lambaré 873, Ciudad de Buenos A"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/Noticias/2009/index.html b/Noticias/2009/index.html index 10fa7bd58..c6f29e542 100644 --- a/Noticias/2009/index.html +++ b/Noticias/2009/index.html @@ -26,7 +26,7 @@ VI Conferencia Latinoamericana de Software Libre | Latinoware 2009 Foz do Iguaçu – Paraná – Brasil Del 22/10 al 24/10 se desarrolla este evento y Miembros de Python Argentina estarán presen"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/Noticias/2010/index.html b/Noticias/2010/index.html index 9b4876e31..ffeb18ebe 100644 --- a/Noticias/2010/index.html +++ b/Noticias/2010/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Noticias/2011/index.html b/Noticias/2011/index.html index b0c2eb242..4da4354d1 100644 --- a/Noticias/2011/index.html +++ b/Noticias/2011/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/Noticias/aritmeticadecimal/index.html b/Noticias/aritmeticadecimal/index.html index 34b74f260..d0a58a343 100644 --- a/Noticias/aritmeticadecimal/index.html +++ b/Noticias/aritmeticadecimal/index.html @@ -27,7 +27,7 @@ Castellano English"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/Noticias/fotobymail/index.html b/Noticias/fotobymail/index.html index c59025054..e312262b6 100644 --- a/Noticias/fotobymail/index.html +++ b/Noticias/fotobymail/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Noticias/gvrybandera/index.html b/Noticias/gvrybandera/index.html index 1605ca283..b7a3865d3 100644 --- a/Noticias/gvrybandera/index.html +++ b/Noticias/gvrybandera/index.html @@ -27,7 +27,7 @@ Adjuntos (incluye foto en tamaño original)"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/Noticias/inmersion54/index.html b/Noticias/inmersion54/index.html index f8f3beea3..6ffb96643 100644 --- a/Noticias/inmersion54/index.html +++ b/Noticias/inmersion54/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/Noticias/listadodepigs/index.html b/Noticias/listadodepigs/index.html index 1fc3c3f7c..ae1924c6c 100644 --- a/Noticias/listadodepigs/index.html +++ b/Noticias/listadodepigs/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/Noticias/python24/index.html b/Noticias/python24/index.html index 7d93673ab..f300432b8 100644 --- a/Noticias/python24/index.html +++ b/Noticias/python24/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Noticias/pythonpalm/index.html b/Noticias/pythonpalm/index.html index 3601f78bd..ade5c8699 100644 --- a/Noticias/pythonpalm/index.html +++ b/Noticias/pythonpalm/index.html @@ -28,7 +28,7 @@ ==== Release Notes ==== Some months ago i did a p'> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/Planeta/config/index.html b/Planeta/config/index.html index 6a8ec875e..9d771dc69 100644 --- a/Planeta/config/index.html +++ b/Planeta/config/index.html @@ -26,7 +26,7 @@ define_name Maximiliano Robaina"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/Proyectos/CDPedia/Prensa/release07/index.html b/Proyectos/CDPedia/Prensa/release07/index.html index 9efb25c21..aad7bed44 100644 --- a/Proyectos/CDPedia/Prensa/release07/index.html +++ b/Proyectos/CDPedia/Prensa/release07/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/Proyectos/CDPedia/Prensa/release08/index.html b/Proyectos/CDPedia/Prensa/release08/index.html index 22b4c9e33..891f3b02a 100644 --- a/Proyectos/CDPedia/Prensa/release08/index.html +++ b/Proyectos/CDPedia/Prensa/release08/index.html @@ -28,7 +28,7 @@ Actualizamos el contenido a Diciembre 2012. Renovamos completamente la gen"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/Proyectos/CDPedia/Prensa/release082/index.html b/Proyectos/CDPedia/Prensa/release082/index.html index 17af41a2e..5914bc690 100644 --- a/Proyectos/CDPedia/Prensa/release082/index.html +++ b/Proyectos/CDPedia/Prensa/release082/index.html @@ -28,7 +28,7 @@ Actualizamos el contenido a Marzo 2014. Uso más eficiente de los recurso"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/Proyectos/CDPedia/changelogs/index.html b/Proyectos/CDPedia/changelogs/index.html index a94d71cec..0efe5a240 100644 --- a/Proyectos/CDPedia/changelogs/index.html +++ b/Proyectos/CDPedia/changelogs/index.html @@ -30,7 +30,7 @@ Set up fixed versions of CDPedia. Merged enhance-home "> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/Proyectos/CDPedia/historia/index.html b/Proyectos/CDPedia/historia/index.html index 6c7dc7c6f..6944f9a1d 100644 --- a/Proyectos/CDPedia/historia/index.html +++ b/Proyectos/CDPedia/historia/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Proyectos/CDPedia/modoservidor/index.html b/Proyectos/CDPedia/modoservidor/index.html index f12569a50..53f5cfde6 100644 --- a/Proyectos/CDPedia/modoservidor/index.html +++ b/Proyectos/CDPedia/modoservidor/index.html @@ -26,7 +26,7 @@ ¿Cómo se arma esto? Si corres ./cdpedia.py --help te mu"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + @@ -89,10 +89,10 @@

Correr Cdpedia Como Servidor

Si corres ./cdpedia.py --help te muestra las opciones, pero básicamente hay 2 formas de montar un servidor. La más sencilla es utilizar el servidor web integrado con cdpedia y es la forma recomendada; la otra es usar un web server externo.

Usando el servidor integrado

Por ejemplo, para servir cdpedia en el puerto 80 en un hostname particular hacemos asi:

-
sudo ./cdpedia.py --host=foo.bar.com.ar --port=80 --daemon
+
sudo ./cdpedia.py --host=foo.bar.com.ar --port=80 --daemon
 

Obviamente el sudo es porque el 80 es un puerto privilegiado, sino directamente podemos poner lo siguiente para servir en una ip local y un puerto elevado.

-
./cdpedia.py --host=10.0.0.4 --port=8080 --daemon
+
./cdpedia.py --host=10.0.0.4 --port=8080 --daemon
 

Inclusive se puede configurar apache o el servidor que haya para que haga las veces de proxy reverso y asi servir todo en el 80.

Usando un server externo (Apache, nginx, etc)

@@ -117,13 +117,13 @@

Correr Cdpedia Como Servidor

) }

apache:

-
ProxyPass / http://127.0.0.1:8888/cdpedia/
-ProxyPassReverse / http://127.0.0.1:8888/cdpedia/
+
ProxyPass / http://127.0.0.1:8888/cdpedia/
+ProxyPassReverse / http://127.0.0.1:8888/cdpedia/
 

nginx:

-
location /cdpedia {
-  proxy_pass        http://127.0.0.1:8888;
-}
+
location /cdpedia {
+  proxy_pass        http://127.0.0.1:8888;
+}
 

WSGI

Esta opción implica no usar el servidor web integrado y en cambio servir utilizando el modulo WSGI del servidor web que se quiera (mod_wsgi para apache, etc). Aún no encontramos razones convincentes de por qué se preferiría esta opcion por sobre el servidor integrado.

diff --git a/Proyectos/CDPedia/prensa/index.html b/Proyectos/CDPedia/prensa/index.html index 7f06f27b0..f2e372cb3 100644 --- a/Proyectos/CDPedia/prensa/index.html +++ b/Proyectos/CDPedia/prensa/index.html @@ -35,7 +35,7 @@ Infobae: Reparten en escuelas argentinas DVD co"> - + Ir al contenido principal @@ -69,12 +69,12 @@ - + diff --git a/Proyectos/CDPedia/versionesanteriores/index.html b/Proyectos/CDPedia/versionesanteriores/index.html index fcde12291..2445dcdba 100644 --- a/Proyectos/CDPedia/versionesanteriores/index.html +++ b/Proyectos/CDPedia/versionesanteriores/index.html @@ -38,7 +38,7 @@ f33a3c71754f645afe1a06780f2d0a058cd3198e http://cdpedia.nqnwebs.com/v0.8/cdpedia-0.8-cd.iso|Directa<<BR>>http://torrentdirecto"> - + Ir al contenido principal @@ -72,12 +72,12 @@ - + diff --git a/Proyectos/GauchitoGil/eventmatching/index.html b/Proyectos/GauchitoGil/eventmatching/index.html index 86c1abe28..046a40b71 100644 --- a/Proyectos/GauchitoGil/eventmatching/index.html +++ b/Proyectos/GauchitoGil/eventmatching/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/PET1/desafio/index.html b/Proyectos/RevistaPythonComunidad/PET1/desafio/index.html index e79b801e9..3069668fd 100644 --- a/Proyectos/RevistaPythonComunidad/PET1/desafio/index.html +++ b/Proyectos/RevistaPythonComunidad/PET1/desafio/index.html @@ -28,7 +28,7 @@ Ranking De esta p"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + @@ -92,13 +92,13 @@

Desafio

De esta página los participantes pueden bajar un programa que les permite validar su prorgama antes de enviarlo.

You can download a program to test your solution.

Uso/Use:

-
   some@example~:$ ./pet1-test.sh pet1-ejemplo.py
-
-
-(pet1-test2 no tiene en cuenta el stderr/ *pet-test2 is like 1 but without stderr*)
+
   some@example~:$ ./pet1-test.sh pet1-ejemplo.py
+
+
+(pet1-test2 no tiene en cuenta el stderr/ *pet-test2 is like 1 but without stderr*)
 

Los caracteres se cuentan con / Characters are counted with:

-
some@example:~$ wc -c pet1-ejemplo.py
+
some@example:~$ wc -c pet1-ejemplo.py
 
diff --git a/Proyectos/RevistaPythonComunidad/PET2/articulos/index.html b/Proyectos/RevistaPythonComunidad/PET2/articulos/index.html index 70fd7635e..be71f3013 100644 --- a/Proyectos/RevistaPythonComunidad/PET2/articulos/index.html +++ b/Proyectos/RevistaPythonComunidad/PET2/articulos/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/PET2/comosehizo/index.html b/Proyectos/RevistaPythonComunidad/PET2/comosehizo/index.html index 6dd8a9411..e16530c3b 100644 --- a/Proyectos/RevistaPythonComunidad/PET2/comosehizo/index.html +++ b/Proyectos/RevistaPythonComunidad/PET2/comosehizo/index.html @@ -44,7 +44,7 @@ Observaciones"> - +Ir al contenido principal @@ -78,12 +78,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/PET2/decoradores/index.html b/Proyectos/RevistaPythonComunidad/PET2/decoradores/index.html index 1dab5f4d2..a53acdcac 100644 --- a/Proyectos/RevistaPythonComunidad/PET2/decoradores/index.html +++ b/Proyectos/RevistaPythonComunidad/PET2/decoradores/index.html @@ -44,7 +44,7 @@ Observaciones"> - +Ir al contenido principal @@ -78,12 +78,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/PET2/depuraciondefragmentacion/index.html b/Proyectos/RevistaPythonComunidad/PET2/depuraciondefragmentacion/index.html index f598790e4..dccfb12ee 100644 --- a/Proyectos/RevistaPythonComunidad/PET2/depuraciondefragmentacion/index.html +++ b/Proyectos/RevistaPythonComunidad/PET2/depuraciondefragmentacion/index.html @@ -44,7 +44,7 @@ Observaciones"> - +Ir al contenido principal @@ -78,12 +78,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/PET2/desafio/index.html b/Proyectos/RevistaPythonComunidad/PET2/desafio/index.html index 1bac424af..4a2e0e95b 100644 --- a/Proyectos/RevistaPythonComunidad/PET2/desafio/index.html +++ b/Proyectos/RevistaPythonComunidad/PET2/desafio/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/PET2/infopython/index.html b/Proyectos/RevistaPythonComunidad/PET2/infopython/index.html index 3ccedbfd4..e23e9a4c8 100644 --- a/Proyectos/RevistaPythonComunidad/PET2/infopython/index.html +++ b/Proyectos/RevistaPythonComunidad/PET2/infopython/index.html @@ -45,7 +45,7 @@ Observaciones Snippets son sintacticamente correctos. No se ejecutaron efectivamente por"> - +Ir al contenido principal @@ -79,12 +79,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/PET2/introdjango/index.html b/Proyectos/RevistaPythonComunidad/PET2/introdjango/index.html index f8683095d..2827b8224 100644 --- a/Proyectos/RevistaPythonComunidad/PET2/introdjango/index.html +++ b/Proyectos/RevistaPythonComunidad/PET2/introdjango/index.html @@ -44,7 +44,7 @@ Observaciones"> - +Ir al contenido principal @@ -78,12 +78,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/PET2/pyafipws/index.html b/Proyectos/RevistaPythonComunidad/PET2/pyafipws/index.html index cd973a7bc..c2f134adb 100644 --- a/Proyectos/RevistaPythonComunidad/PET2/pyafipws/index.html +++ b/Proyectos/RevistaPythonComunidad/PET2/pyafipws/index.html @@ -44,7 +44,7 @@ Observaciones"> - +Ir al contenido principal @@ -78,12 +78,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/base/index.html b/Proyectos/RevistaPythonComunidad/base/index.html index d78a01dc4..a0e67e752 100644 --- a/Proyectos/RevistaPythonComunidad/base/index.html +++ b/Proyectos/RevistaPythonComunidad/base/index.html @@ -27,7 +27,7 @@ Precisamos de un grupo u persona que arme la revista / editores :). Interesados, anotarse en el wiki. [OK] Precisamos de un grupo u persona que este interesada en aportar articulos a la "> - +Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/pet2/index.html b/Proyectos/RevistaPythonComunidad/pet2/index.html index 88fdfe41a..9f304f0b0 100644 --- a/Proyectos/RevistaPythonComunidad/pet2/index.html +++ b/Proyectos/RevistaPythonComunidad/pet2/index.html @@ -38,7 +38,7 @@ la autoría de las fotos corresponde a ellos las fotos tienen licencias Creative Commons "> - +Ir al contenido principal @@ -72,12 +72,12 @@ - + diff --git a/Proyectos/RevistaPythonComunidad/release1/index.html b/Proyectos/RevistaPythonComunidad/release1/index.html index 03f770449..151ffa88e 100644 --- a/Proyectos/RevistaPythonComunidad/release1/index.html +++ b/Proyectos/RevistaPythonComunidad/release1/index.html @@ -33,7 +33,7 @@ Articuladores Se envia "> - +Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/Proyectos/alocadoalocador/index.html b/Proyectos/alocadoalocador/index.html index ba5959da2..16e249c20 100644 --- a/Proyectos/alocadoalocador/index.html +++ b/Proyectos/alocadoalocador/index.html @@ -26,7 +26,7 @@ Un juego en 53 KB de puro código Python y pygame. Hecho para pydraw2006 https://opensvn.csie.org/PyAr/pydraw2006/release/"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/Proyectos/caucho/index.html b/Proyectos/caucho/index.html index f93f0fc28..2cc4812e8 100644 --- a/Proyectos/caucho/index.html +++ b/Proyectos/caucho/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Proyectos/cdpedia/index.html b/Proyectos/cdpedia/index.html index 549951a63..e5c5dec45 100644 --- a/Proyectos/cdpedia/index.html +++ b/Proyectos/cdpedia/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Proyectos/gauchitogil/index.html b/Proyectos/gauchitogil/index.html index 46373f41b..8a4dd1e86 100644 --- a/Proyectos/gauchitogil/index.html +++ b/Proyectos/gauchitogil/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Proyectos/geine/index.html b/Proyectos/geine/index.html index 1aad0c489..538fdbe1e 100644 --- a/Proyectos/geine/index.html +++ b/Proyectos/geine/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Proyectos/getesfi/index.html b/Proyectos/getesfi/index.html index 211e1b130..8229281ee 100644 --- a/Proyectos/getesfi/index.html +++ b/Proyectos/getesfi/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Proyectos/pythonpalm/index.html b/Proyectos/pythonpalm/index.html index e6aa7a53f..0d2418ea6 100644 --- a/Proyectos/pythonpalm/index.html +++ b/Proyectos/pythonpalm/index.html @@ -29,7 +29,7 @@ Release Notes Some month"> - +Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/Proyectos/revistapythoncomunidad/index.html b/Proyectos/revistapythoncomunidad/index.html index ee649adf0..90f32a27a 100644 --- a/Proyectos/revistapythoncomunidad/index.html +++ b/Proyectos/revistapythoncomunidad/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/Proyectos/stim/index.html b/Proyectos/stim/index.html index 1437e2958..5ccb9dedb 100644 --- a/Proyectos/stim/index.html +++ b/Proyectos/stim/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/Proyectos/tweetyfinger/index.html b/Proyectos/tweetyfinger/index.html index 613965aa3..1fe3f2258 100644 --- a/Proyectos/tweetyfinger/index.html +++ b/Proyectos/tweetyfinger/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/Proyectos/unmanualencadauniversidad/index.html b/Proyectos/unmanualencadauniversidad/index.html index 884d1b87c..706c772d8 100644 --- a/Proyectos/unmanualencadauniversidad/index.html +++ b/Proyectos/unmanualencadauniversidad/index.html @@ -32,7 +32,7 @@ Title underline too short. ¿Cómo co"> - +Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/Proyectos/usodepythonenlauniversidad/index.html b/Proyectos/usodepythonenlauniversidad/index.html index ffae6e68d..0c6c1f20c 100644 --- a/Proyectos/usodepythonenlauniversidad/index.html +++ b/Proyectos/usodepythonenlauniversidad/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/PyCamp/2009/TemasPropuestos/sprintdjango/index.html b/PyCamp/2009/TemasPropuestos/sprintdjango/index.html index 31c35af5d..3341d190c 100644 --- a/PyCamp/2009/TemasPropuestos/sprintdjango/index.html +++ b/PyCamp/2009/TemasPropuestos/sprintdjango/index.html @@ -39,7 +39,7 @@ Un checkout del trunk de Dj"> - +Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/PyCamp/2009/comollegar/index.html b/PyCamp/2009/comollegar/index.html index 5694c7593..27a50b43f 100644 --- a/PyCamp/2009/comollegar/index.html +++ b/PyCamp/2009/comollegar/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2009/fotos/index.html b/PyCamp/2009/fotos/index.html index 04416c645..564049e96 100644 --- a/PyCamp/2009/fotos/index.html +++ b/PyCamp/2009/fotos/index.html @@ -27,7 +27,7 @@ http://www.flickr.com/photos/ramiro_morales/sets/72157615817351413/ http://www.flickr.com/"> - +Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/PyCamp/2009/index.html b/PyCamp/2009/index.html index 11830713c..b285378b8 100644 --- a/PyCamp/2009/index.html +++ b/PyCamp/2009/index.html @@ -38,7 +38,7 @@ Qué hace falta que alguien lleve Qué conviene tener en "> - +Ir al contenido principal @@ -72,12 +72,12 @@ - + diff --git a/PyCamp/2009/naushikang/index.html b/PyCamp/2009/naushikang/index.html index 5f378a58c..18e202b34 100644 --- a/PyCamp/2009/naushikang/index.html +++ b/PyCamp/2009/naushikang/index.html @@ -29,7 +29,7 @@ @foto_esta <url>: agrega la url tal como foto del qu"> - +Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/PyCamp/2009/programa/index.html b/PyCamp/2009/programa/index.html index 8ca554b29..56c374765 100644 --- a/PyCamp/2009/programa/index.html +++ b/PyCamp/2009/programa/index.html @@ -45,7 +45,7 @@ Karma Sysadmining TracUSLA Reunion"> - +Ir al contenido principal @@ -79,12 +79,12 @@ - + diff --git a/PyCamp/2009/quienesvan/index.html b/PyCamp/2009/quienesvan/index.html index 9038140f8..6252e6099 100644 --- a/PyCamp/2009/quienesvan/index.html +++ b/PyCamp/2009/quienesvan/index.html @@ -30,7 +30,7 @@ FacundoBatista: desde el sábado a las 10, hasta el martes a las 19, morfo con todos, duermo "> - +Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/PyCamp/2009/requerimientosdietarios/index.html b/PyCamp/2009/requerimientosdietarios/index.html index 5393a9d53..b62a7ec5c 100644 --- a/PyCamp/2009/requerimientosdietarios/index.html +++ b/PyCamp/2009/requerimientosdietarios/index.html @@ -39,7 +39,7 @@ Semi Vegetariano http://en.wikipedia.org/wiki/Semi_Vegetarian ("> - +Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/PyCamp/2009/temaspropuestos/index.html b/PyCamp/2009/temaspropuestos/index.html index 8d8a39f8c..71485a50d 100644 --- a/PyCamp/2009/temaspropuestos/index.html +++ b/PyCamp/2009/temaspropuestos/index.html @@ -32,7 +32,7 @@ Fa"> - +Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/PyCamp/2009/transporte/index.html b/PyCamp/2009/transporte/index.html index ba632a5f0..1c0c1162b 100644 --- a/PyCamp/2009/transporte/index.html +++ b/PyCamp/2009/transporte/index.html @@ -45,7 +45,7 @@ RicardoKirkner Buenos Aire"> - +Ir al contenido principal @@ -79,12 +79,12 @@ - + diff --git a/PyCamp/2010/attic/index.html b/PyCamp/2010/attic/index.html index 8858241c6..5982b5477 100644 --- a/PyCamp/2010/attic/index.html +++ b/PyCamp/2010/attic/index.html @@ -36,7 +36,7 @@ Feb-Mayo"> - +Ir al contenido principal @@ -70,12 +70,12 @@ - + diff --git a/PyCamp/2010/cronograma/index.html b/PyCamp/2010/cronograma/index.html index 531d228bc..52c6a0d38 100644 --- a/PyCamp/2010/cronograma/index.html +++ b/PyCamp/2010/cronograma/index.html @@ -48,7 +48,7 @@ Empaquetado en Debian/Ubuntu (18) E"> - +Ir al contenido principal @@ -82,12 +82,12 @@ - + diff --git a/PyCamp/2010/delinterior/index.html b/PyCamp/2010/delinterior/index.html index 080def004..beec1521f 100644 --- a/PyCamp/2010/delinterior/index.html +++ b/PyCamp/2010/delinterior/index.html @@ -30,7 +30,7 @@ llego a retiro el 05/03 a las 7:00 hs aprox. si al"> - +Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/PyCamp/2010/index.html b/PyCamp/2010/index.html index 54677bed4..dbf75cdb6 100644 --- a/PyCamp/2010/index.html +++ b/PyCamp/2010/index.html @@ -46,7 +46,7 @@ Hogar Escuel"> - +Ir al contenido principal @@ -80,12 +80,12 @@ - + diff --git a/PyCamp/2010/interesados/index.html b/PyCamp/2010/interesados/index.html index ae22f9a2c..edcc30a51 100644 --- a/PyCamp/2010/interesados/index.html +++ b/PyCamp/2010/interesados/index.html @@ -26,7 +26,7 @@ Esta es la lista de interesados, para confirma"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/PyCamp/2010/pendientes/index.html b/PyCamp/2010/pendientes/index.html index 35aa55ce4..d929aa20b 100644 --- a/PyCamp/2010/pendientes/index.html +++ b/PyCamp/2010/pendientes/index.html @@ -30,7 +30,7 @@ invitar a la gente: mandado el mail de invitación c"> - +Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/PyCamp/2010/quellevar/index.html b/PyCamp/2010/quellevar/index.html index f6d96a5df..ac1fef61e 100644 --- a/PyCamp/2010/quellevar/index.html +++ b/PyCamp/2010/quellevar/index.html @@ -33,7 +33,7 @@ Sábanas (frazadas hay) cable "> - +Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/PyCamp/2010/temaspropuestos/index.html b/PyCamp/2010/temaspropuestos/index.html index 183c0f062..34d69b6be 100644 --- a/PyCamp/2010/temaspropuestos/index.html +++ b/PyCamp/2010/temaspropuestos/index.html @@ -28,7 +28,7 @@ FacundoBatista JoaquinSoria"> - +Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/PyCamp/2010/torneopingpong/index.html b/PyCamp/2010/torneopingpong/index.html index d11c4b61f..3a413874c 100644 --- a/PyCamp/2010/torneopingpong/index.html +++ b/PyCamp/2010/torneopingpong/index.html @@ -34,7 +34,7 @@ Puede ser hoy (Sábado) por la noche, pero no sabemos si v"> - +Ir al contenido principal @@ -68,12 +68,12 @@ - + diff --git a/PyCamp/2011/desdecordobacapital/index.html b/PyCamp/2011/desdecordobacapital/index.html index ba0191605..8b4745bd3 100644 --- a/PyCamp/2011/desdecordobacapital/index.html +++ b/PyCamp/2011/desdecordobacapital/index.html @@ -35,7 +35,7 @@ Emil"> - +Ir al contenido principal @@ -69,12 +69,12 @@ - + diff --git a/PyCamp/2011/index.html b/PyCamp/2011/index.html index 866f30ba3..9bf1537ce 100644 --- a/PyCamp/2011/index.html +++ b/PyCamp/2011/index.html @@ -38,7 +38,7 @@ contacto: Juan A. Diaz (nueces) prec"> - +Ir al contenido principal @@ -72,12 +72,12 @@ - + diff --git a/PyCamp/2011/interesados/index.html b/PyCamp/2011/interesados/index.html index 5ee66a958..ed216e6b2 100644 --- a/PyCamp/2011/interesados/index.html +++ b/PyCamp/2011/interesados/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2011/proyectoslaburados/index.html b/PyCamp/2011/proyectoslaburados/index.html index cfcd97f61..fa0500715 100644 --- a/PyCamp/2011/proyectoslaburados/index.html +++ b/PyCamp/2011/proyectoslaburados/index.html @@ -28,7 +28,7 @@ geoarcade: Con el objetivo de introducir a nuevos en Dja"> - +Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/PyCamp/2011/quellevar/index.html b/PyCamp/2011/quellevar/index.html index 14a7618b2..3a3010fb1 100644 --- a/PyCamp/2011/quellevar/index.html +++ b/PyCamp/2011/quellevar/index.html @@ -37,7 +37,7 @@ Gi"> - +Ir al contenido principal @@ -71,12 +71,12 @@ - + diff --git a/PyCamp/2011/temasdesarrollados/index.html b/PyCamp/2011/temasdesarrollados/index.html index fc4eb207d..f3dea9d43 100644 --- a/PyCamp/2011/temasdesarrollados/index.html +++ b/PyCamp/2011/temasdesarrollados/index.html @@ -30,7 +30,7 @@ pilasnet grafo wiki PyAr"> - +Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/PyCamp/2011/temaspropuestos/index.html b/PyCamp/2011/temaspropuestos/index.html index 6e40e2480..a107bc879 100644 --- a/PyCamp/2011/temaspropuestos/index.html +++ b/PyCamp/2011/temaspropuestos/index.html @@ -27,7 +27,7 @@ Fa"> - +Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/PyCamp/2012/TemasPropuestos/editordeebooks/index.html b/PyCamp/2012/TemasPropuestos/editordeebooks/index.html index 1fced2864..aeaa8b6a8 100644 --- a/PyCamp/2012/TemasPropuestos/editordeebooks/index.html +++ b/PyCamp/2012/TemasPropuestos/editordeebooks/index.html @@ -26,7 +26,7 @@ Aunque no "apocalípticamente" como alguno preveían, la lectura de libros electrónicos se hace cada más popular. Los lectores de libros electrónicos como el Kindle son cada vez más accesible'> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/PyCamp/2012/cronograma/index.html b/PyCamp/2012/cronograma/index.html index be7c4c2ff..1d0959c49 100644 --- a/PyCamp/2012/cronograma/index.html +++ b/PyCamp/2012/cronograma/index.html @@ -94,7 +94,7 @@ Reunion Pyar"> - +Ir al contenido principal @@ -128,12 +128,12 @@ - + diff --git a/PyCamp/2012/index.html b/PyCamp/2012/index.html index 653eb5e80..39c3547f4 100644 --- a/PyCamp/2012/index.html +++ b/PyCamp/2012/index.html @@ -42,7 +42,7 @@ de la Comunidad de Escuelas Argentino-"> - +Ir al contenido principal @@ -76,12 +76,12 @@ - + diff --git a/PyCamp/2012/interesados/index.html b/PyCamp/2012/interesados/index.html index 4e5f680ef..b8f53a01e 100644 --- a/PyCamp/2012/interesados/index.html +++ b/PyCamp/2012/interesados/index.html @@ -26,7 +26,7 @@ La inscripcion tiene dos etapas importantes: Etapa 1: Para reservar la fecha n"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/PyCamp/2012/kinect/index.html b/PyCamp/2012/kinect/index.html index 94fe719d8..05dd4e761 100644 --- a/PyCamp/2012/kinect/index.html +++ b/PyCamp/2012/kinect/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/PyCamp/2012/proyectos/index.html b/PyCamp/2012/proyectos/index.html index f06119b14..9ebaf232e 100644 --- a/PyCamp/2012/proyectos/index.html +++ b/PyCamp/2012/proyectos/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -107,17 +107,17 @@

Proyectos En Los Que Se Trabajó Durante El Pycamp 2012

  • Usar el modo de edición de vim desde la línea de comandos (funciona en la consola de python):

-
     set -o vi # bash
-     bindkey -v # zsh
-
-Agregarlo al .bashrc o .zshrc respec. También se puede setear creando un .inputrc (en bash)
+
     set -o vi # bash
+     bindkey -v # zsh
+
+Agregarlo al .bashrc o .zshrc respec. También se puede setear creando un .inputrc (en bash)
 
-
     set editing-mode vi
-     set keymap vi
-
-Hay muchas más opciones que se pueden setear (man 3 readline).
-
-Lista de comandos: `Bash vi editing mode cheat sheet`_
+
     set editing-mode vi
+     set keymap vi
+
+Hay muchas más opciones que se pueden setear (man 3 readline).
+
+Lista de comandos: `Bash vi editing mode cheat sheet`_
 

También vimos muchos plugins y cosas interesantes para agregarle a vim y que sea un mejor entorno de desarrollo con python. La mayoría está en https://github.com/fisadev/fisa-vim-config . Descubrimos que dos no andaban, uno ya está corregido (el que todavía no anda es el debugger, pero ya está identificado el problema). Y surgió la idea de meter el autocompletado de ninja ide en vim (como plugin). La gente de ninja va a separar la lógica del autocompletado como proyecto aparte, y nosotros vamos a meterlo en vim.

Spacecraft

diff --git a/PyCamp/2012/quellevar/index.html b/PyCamp/2012/quellevar/index.html index e55fc4b77..6830fe460 100644 --- a/PyCamp/2012/quellevar/index.html +++ b/PyCamp/2012/quellevar/index.html @@ -36,7 +36,7 @@ Si tenes un rat"> - + Ir al contenido principal @@ -70,12 +70,12 @@ - +
diff --git a/PyCamp/2012/temaspropuestos/index.html b/PyCamp/2012/temaspropuestos/index.html index 1eb1fccb6..bac07dded 100644 --- a/PyCamp/2012/temaspropuestos/index.html +++ b/PyCamp/2012/temaspropuestos/index.html @@ -29,7 +29,7 @@ ccane"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - +
diff --git a/PyCamp/2012/workshop/index.html b/PyCamp/2012/workshop/index.html index 0b200f432..bb404415f 100644 --- a/PyCamp/2012/workshop/index.html +++ b/PyCamp/2012/workshop/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2013/PosiblesSedes/votos/index.html b/PyCamp/2013/PosiblesSedes/votos/index.html index 9f5dcefd6..f46240855 100644 --- a/PyCamp/2013/PosiblesSedes/votos/index.html +++ b/PyCamp/2013/PosiblesSedes/votos/index.html @@ -31,7 +31,7 @@ Estas fueron las votaciones en detalle: Facundo Ba"> - +Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/PyCamp/2013/becas/index.html b/PyCamp/2013/becas/index.html index b9992558a..00666ada6 100644 --- a/PyCamp/2013/becas/index.html +++ b/PyCamp/2013/becas/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2013/habitaciones/index.html b/PyCamp/2013/habitaciones/index.html index 31285a7af..84f892282 100644 --- a/PyCamp/2013/habitaciones/index.html +++ b/PyCamp/2013/habitaciones/index.html @@ -29,7 +29,7 @@ No hay garantía 100% de que se respete esto a rajatabla, pero lo más probable es"> - +Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/PyCamp/2013/index.html b/PyCamp/2013/index.html index 5508a596e..f3d02c3ec 100644 --- a/PyCamp/2013/index.html +++ b/PyCamp/2013/index.html @@ -29,7 +29,7 @@ https://"> - +Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/PyCamp/2013/posiblessedes/index.html b/PyCamp/2013/posiblessedes/index.html index d0555bb33..f9b3554f4 100644 --- a/PyCamp/2013/posiblessedes/index.html +++ b/PyCamp/2013/posiblessedes/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2013/temaspropuestos/index.html b/PyCamp/2013/temaspropuestos/index.html index 7a7a0269d..0764eab0f 100644 --- a/PyCamp/2013/temaspropuestos/index.html +++ b/PyCamp/2013/temaspropuestos/index.html @@ -26,7 +26,7 @@ S"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/PyCamp/2014/PosiblesSedes/votos/index.html b/PyCamp/2014/PosiblesSedes/votos/index.html index fc3ffa040..17d436043 100644 --- a/PyCamp/2014/PosiblesSedes/votos/index.html +++ b/PyCamp/2014/PosiblesSedes/votos/index.html @@ -36,7 +36,7 @@ Diego Sarmentero Hotel L"> - +Ir al contenido principal @@ -70,12 +70,12 @@ - + diff --git a/PyCamp/2014/becas/index.html b/PyCamp/2014/becas/index.html index 71d0a6331..fed5b65c7 100644 --- a/PyCamp/2014/becas/index.html +++ b/PyCamp/2014/becas/index.html @@ -26,7 +26,7 @@ Este año también habrán becas para facilitar el ir al PyCamp. La idea es subvencionar lo más posible del costo total del PyCamp, en función de la cantidad de becas pe"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/PyCamp/2014/index.html b/PyCamp/2014/index.html index 92005f0b7..a5a607807 100644 --- a/PyCamp/2014/index.html +++ b/PyCamp/2014/index.html @@ -29,7 +29,7 @@ https://www.flickr.com/photos/121373908@N03/ http://www.flickr.com/photos/p"> - +Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/PyCamp/2014/posiblessedes/index.html b/PyCamp/2014/posiblessedes/index.html index a58b12e1a..1c5188a4a 100644 --- a/PyCamp/2014/posiblessedes/index.html +++ b/PyCamp/2014/posiblessedes/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2014/rooming/index.html b/PyCamp/2014/rooming/index.html index d03c48dd5..1b6686fa3 100644 --- a/PyCamp/2014/rooming/index.html +++ b/PyCamp/2014/rooming/index.html @@ -28,7 +28,7 @@ Habitaciones triples Esto es"> - +Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/PyCamp/2014/temaspropuestos/index.html b/PyCamp/2014/temaspropuestos/index.html index 2bf5ec980..b73a374f3 100644 --- a/PyCamp/2014/temaspropuestos/index.html +++ b/PyCamp/2014/temaspropuestos/index.html @@ -26,7 +26,7 @@ L"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + @@ -135,7 +135,7 @@

Temas Propuestos Para El Pycamp 2014

  • Crear tu keypair, usar los algoritmo RSA y SHA2, se sugiere usar un tamaño de 4096 bits

  • Imprimir varias etiquetas conteniendo información sobre tu keypair. Por ejemplo, múltlples copias por página de la salida del siguiente comando

  • -
    gpg -v --fingerprint <ID de tu keypair>
    +
    gpg -v --fingerprint <ID de tu keypair>
     

    o usando la utilidad gpg-key2ps del paquete signing-party (Debian/Ubuntu)

      diff --git a/PyCamp/2015/PosiblesSedes/votos/index.html b/PyCamp/2015/PosiblesSedes/votos/index.html index 5d679b20b..ed2602f2b 100644 --- a/PyCamp/2015/PosiblesSedes/votos/index.html +++ b/PyCamp/2015/PosiblesSedes/votos/index.html @@ -26,7 +26,7 @@ Para ver las posibles sedes podes verlo por acá Si no po"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    diff --git a/PyCamp/2015/actividades/index.html b/PyCamp/2015/actividades/index.html index 9db7c6cd0..126869eb5 100644 --- a/PyCamp/2015/actividades/index.html +++ b/PyCamp/2015/actividades/index.html @@ -29,7 +29,7 @@ Tenemos un pip-cache funcionando en el host alarm. ¡¡Por favor utilizarlo!! Hay dos maneras de usarlo, la más simpl"> - +Ir al contenido principal @@ -63,12 +63,12 @@ - + @@ -92,15 +92,15 @@

    Alineador De Antenas

    pip-cache

    Tenemos un pip-cache funcionando en el host alarm. ¡¡Por favor utilizarlo!!

    Hay dos maneras de usarlo, la más simple (pero tenes que acordarte el comando)

    -
    pip install -i http://alarm:3141/root/pypi/ <paquete>
    +
    pip install -i http://alarm:3141/root/pypi/ <paquete>
     

    La otra es editar ~/.pip/pip.conf y dejar la config fija:

    -
    [global]
    -index-url = http://10.5.20.252:3141/root/pypi/+simple/
    -trusted-host = 10.5.20.252
    -disable-pip-version-check = true
    -allow-all-external=true
    -timeout = 120
    +
    [global]
    +index-url = http://10.5.20.252:3141/root/pypi/+simple/
    +trusted-host = 10.5.20.252
    +disable-pip-version-check = true
    +allow-all-external=true
    +timeout = 120
     

    Cronograma de actividades 2015:

    @@ -177,7 +177,7 @@

    Alineador De Antenas

    Los nodos ya entregan por http un json con la data necesaria. Por ej: http://oncelotes-bbone/cgi-bin/luci/status/json/stations/wlan1-adhoc

    devuelve:

    -
    [ { "type": "wifi", "station_hostname": "czuk-bbone_wlan1-adhoc", "station": "C0:4A:00:FC:3A:89", "attributes": { "inactive": 0, "channel": 36, "signal": -80 } }, { "type": "wifi", "station_hostname": "giordano-bbone_wlan1-adhoc", "station": "C0:4A:00:FC:38:E1", "attributes": { "inactive": 0, "channel": 36, "signal": -75 } } ]
    +
    [ { "type": "wifi", "station_hostname": "czuk-bbone_wlan1-adhoc", "station": "C0:4A:00:FC:3A:89", "attributes": { "inactive": 0, "channel": 36, "signal": -80 } }, { "type": "wifi", "station_hostname": "giordano-bbone_wlan1-adhoc", "station": "C0:4A:00:FC:38:E1", "attributes": { "inactive": 0, "channel": 36, "signal": -75 } } ]
     

    La idea entonces sería consumir esto desde la mini app.

    [Propone: NicoEchániz]

    diff --git a/PyCamp/2015/index.html b/PyCamp/2015/index.html index 3a42e4362..60a7d21e5 100644 --- a/PyCamp/2015/index.html +++ b/PyCamp/2015/index.html @@ -31,7 +31,7 @@ Zapatillas, prolongadores, proyector, access points que puedas "> - + Ir al contenido principal @@ -65,12 +65,12 @@ - +
    diff --git a/PyCamp/2015/posiblessedes/index.html b/PyCamp/2015/posiblessedes/index.html index 3f32d46e9..2b3682c67 100644 --- a/PyCamp/2015/posiblessedes/index.html +++ b/PyCamp/2015/posiblessedes/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2016/Actividades/test/index.html b/PyCamp/2016/Actividades/test/index.html index 39eeaaa0f..d1f3ca05b 100644 --- a/PyCamp/2016/Actividades/test/index.html +++ b/PyCamp/2016/Actividades/test/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/PyCamp/2016/actividades/index.html b/PyCamp/2016/actividades/index.html index 918573d5e..7b9e0d14b 100644 --- a/PyCamp/2016/actividades/index.html +++ b/PyCamp/2016/actividades/index.html @@ -26,7 +26,7 @@ L"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/PyCamp/2016/index.html b/PyCamp/2016/index.html index 962d44ed8..61d309d36 100644 --- a/PyCamp/2016/index.html +++ b/PyCamp/2016/index.html @@ -35,7 +35,7 @@ Fechas: 2"> - + Ir al contenido principal @@ -69,12 +69,12 @@ - + @@ -189,12 +189,12 @@

    Fotos!

    Conectate con cualquier cliente de irc al server en 192.168.1.100, canal #pycamp

    Mirror PyPI

    Agregá esto al final de tu archivo /etc/hosts:

    -
    192.168.1.100 pypi.pycamp
    +
    192.168.1.100 pypi.pycamp
     

    Y agregá esto en tu archivo /home/tuuser/.pip/pip.conf:

    -
    [global]
    -index-url = http://pypi.pycamp/simple
    -trusted-host = pypi.pycamp
    +
    [global]
    +index-url = http://pypi.pycamp/simple
    +trusted-host = pypi.pycamp
     

    Yastá! ahora podés hacer pip install y va a volar (a la velocidad de una raspi y nuestro wifi)

    diff --git a/PyCamp/2016/posiblessedes/index.html b/PyCamp/2016/posiblessedes/index.html index ce02a5a45..018a0f8f7 100644 --- a/PyCamp/2016/posiblessedes/index.html +++ b/PyCamp/2016/posiblessedes/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2017/actividades/index.html b/PyCamp/2017/actividades/index.html index 7635e875f..d990a2d3c 100644 --- a/PyCamp/2017/actividades/index.html +++ b/PyCamp/2017/actividades/index.html @@ -26,7 +26,7 @@ f"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/PyCamp/2017/ayudaeconomica/index.html b/PyCamp/2017/ayudaeconomica/index.html index 4bbca67b8..cb192772f 100644 --- a/PyCamp/2017/ayudaeconomica/index.html +++ b/PyCamp/2017/ayudaeconomica/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2017/index.html b/PyCamp/2017/index.html index c2f9abd80..aa11a7d6e 100644 --- a/PyCamp/2017/index.html +++ b/PyCamp/2017/index.html @@ -32,7 +32,7 @@ ASL1@pyar y ASL2@pyar. "> - +Ir al contenido principal @@ -66,12 +66,12 @@ - + @@ -172,12 +172,12 @@

    ¿un Qué?

    Conectate con cualquier cliente de irc al server en 192.168.1.100, canal #pycamp

    Mirror PyPI

    Agregá esto al final de tu archivo /etc/hosts:

    -
    192.168.1.100 pypi.pycamp
    +
    192.168.1.100 pypi.pycamp
     

    Y agregá esto en tu archivo /home/tuuser/.pip/pip.conf:

    -
    [global]
    -index-url = http://pypi.pycamp/simple
    -trusted-host = pypi.pycamp
    +
    [global]
    +index-url = http://pypi.pycamp/simple
    +trusted-host = pypi.pycamp
     

    astá! ahora podés hacer pip install y va a volar (a la velocidad de una raspi y nuestro wifi)

    diff --git a/PyCamp/2017/posiblessedes/index.html b/PyCamp/2017/posiblessedes/index.html index c8f1eac88..d1b0347ae 100644 --- a/PyCamp/2017/posiblessedes/index.html +++ b/PyCamp/2017/posiblessedes/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2018/actividades/index.html b/PyCamp/2018/actividades/index.html index ddfd2eea0..6c9306e82 100644 --- a/PyCamp/2018/actividades/index.html +++ b/PyCamp/2018/actividades/index.html @@ -27,7 +27,7 @@ Uso de Eventol en PyAr y mejoras para el sistema Eventol es un proyecto libre que busca facilitar la administración y difusión "> - +Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/PyCamp/2018/index.html b/PyCamp/2018/index.html index 23b23afaa..fadb78ced 100644 --- a/PyCamp/2018/index.html +++ b/PyCamp/2018/index.html @@ -27,7 +27,7 @@ Fechas: 28, 29, 30 de abril y 1 de mayo de 2018 (sábado, domingo, lunes y martes feriados (ambos) por el Día del Trab"> - +Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/PyCamp/2018rst/index.html b/PyCamp/2018rst/index.html index 40f5bcce6..d49e74c83 100644 --- a/PyCamp/2018rst/index.html +++ b/PyCamp/2018rst/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/PyCamp/2019/actividades/index.html b/PyCamp/2019/actividades/index.html index 908c5d320..74df669d9 100644 --- a/PyCamp/2019/actividades/index.html +++ b/PyCamp/2019/actividades/index.html @@ -27,7 +27,7 @@ fades Fixear algún bug o meter algún feature en fades (fades is a system that automatically handles the virtualenvs in the case"> - +Ir al contenido principal @@ -61,12 +61,12 @@ - + @@ -124,8 +124,8 @@

    Actividades

    Grillo

    Hoy hice Grillo, una herramienta que permite mandar datos de una máquina a otra re re fácil, usando micrófono y parlantes para transmitir y leer la data por audio. Tiene magias como esta:

    -
    maquina1> grillo listen
    -maquina2> grillo clipboard
    +
    maquina1> grillo listen
    +maquina2> grillo clipboard
     

    Y después de escuchar un ruido, máquina 1 tiene en su clipboard el contenido que tiene el clipboard de máquina 2. Sirve para mandar textos y archivos también.

    diff --git a/PyCamp/2019/index.html b/PyCamp/2019/index.html index 7c73d68e5..40f1599ad 100644 --- a/PyCamp/2019/index.html +++ b/PyCamp/2019/index.html @@ -30,7 +30,7 @@ Qué ll"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - +
    diff --git a/PyCamp/2019/posiblessedes/index.html b/PyCamp/2019/posiblessedes/index.html index ec03b8764..5b7e62f8e 100644 --- a/PyCamp/2019/posiblessedes/index.html +++ b/PyCamp/2019/posiblessedes/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/2020/index.html b/PyCamp/2020/index.html index d6e160e87..91266cc29 100644 --- a/PyCamp/2020/index.html +++ b/PyCamp/2020/index.html @@ -27,7 +27,7 @@ Fechas: 21, 22, 23 y 24 de marzo (sábado, domingo, lunes (feriado puente) y martes feriado por el Día Nacional de la Memoria por la Verdad y la J"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/PyCamp/2021/index.html b/PyCamp/2021/index.html index 254160aa1..9f65a3657 100644 --- a/PyCamp/2021/index.html +++ b/PyCamp/2021/index.html @@ -33,7 +33,7 @@ Zapatillas, prolongadores, pr"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/PyCamp/2022/index.html b/PyCamp/2022/index.html index 2bc74c601..70e43ac6e 100644 --- a/PyCamp/2022/index.html +++ b/PyCamp/2022/index.html @@ -33,7 +33,7 @@ Zapatillas, p"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/PyCamp/2023/index.html b/PyCamp/2023/index.html index a8009efa9..18489db8b 100644 --- a/PyCamp/2023/index.html +++ b/PyCamp/2023/index.html @@ -32,7 +32,7 @@ Zapatillas,"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/PyCamp/2024/index.html b/PyCamp/2024/index.html index a376535cf..1ae8afc9c 100644 --- a/PyCamp/2024/index.html +++ b/PyCamp/2024/index.html @@ -26,7 +26,7 @@ Actividades Show&Tell de configuraciones y herramientas"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/PyCamp/2024/showntell2024/index.html b/PyCamp/2024/showntell2024/index.html index b2ec964f0..8e90a21ed 100644 --- a/PyCamp/2024/showntell2024/index.html +++ b/PyCamp/2024/showntell2024/index.html @@ -26,7 +26,7 @@ Andre Sublime-T"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/PyCamp/PyCamp/2018/index.html b/PyCamp/PyCamp/2018/index.html index 62263882a..87999a6a2 100644 --- a/PyCamp/PyCamp/2018/index.html +++ b/PyCamp/PyCamp/2018/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/PyCamp/coc/index.html b/PyCamp/coc/index.html index 406542813..eacf831e4 100644 --- a/PyCamp/coc/index.html +++ b/PyCamp/coc/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyCamp/howto/index.html b/PyCamp/howto/index.html index 5c26d66fb..fe09c2aa0 100644 --- a/PyCamp/howto/index.html +++ b/PyCamp/howto/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/PyCamp/organizandounpycamp/index.html b/PyCamp/organizandounpycamp/index.html index e3deb0581..395389919 100644 --- a/PyCamp/organizandounpycamp/index.html +++ b/PyCamp/organizandounpycamp/index.html @@ -28,7 +28,7 @@ El lugar debe contar con idealmente con espacio para albergar entre unas 35 y 50 personas aproximadamente (basado en la cantidad histórica de asistentes). Aunque exist"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/PyCamp/quesehace/index.html b/PyCamp/quesehace/index.html index 13a13b588..94b3d67ed 100644 --- a/PyCamp/quesehace/index.html +++ b/PyCamp/quesehace/index.html @@ -28,7 +28,7 @@ Los interesados en proponer temas hacen un brevísimo speech para proponer una actividad, "> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/PyConArgentina/2009/alojamientocompartido/index.html b/PyConArgentina/2009/alojamientocompartido/index.html index 54b83689f..1473afc79 100644 --- a/PyConArgentina/2009/alojamientocompartido/index.html +++ b/PyConArgentina/2009/alojamientocompartido/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyConArgentina/2009/transportecompartido/index.html b/PyConArgentina/2009/transportecompartido/index.html index f91be773c..675b324b2 100644 --- a/PyConArgentina/2009/transportecompartido/index.html +++ b/PyConArgentina/2009/transportecompartido/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyConArgentina/2012/alojamientocompartido/index.html b/PyConArgentina/2012/alojamientocompartido/index.html index fc96042c7..a478723c3 100644 --- a/PyConArgentina/2012/alojamientocompartido/index.html +++ b/PyConArgentina/2012/alojamientocompartido/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyConArgentina/2012/distribucionafiches/index.html b/PyConArgentina/2012/distribucionafiches/index.html index 8286d74d2..6ef701431 100644 --- a/PyConArgentina/2012/distribucionafiches/index.html +++ b/PyConArgentina/2012/distribucionafiches/index.html @@ -29,7 +29,7 @@ Como colaborar Si estas cerca o tenes al"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/PyConArgentina/2012/encargadosaula/index.html b/PyConArgentina/2012/encargadosaula/index.html index c49bdd988..23e09b380 100644 --- a/PyConArgentina/2012/encargadosaula/index.html +++ b/PyConArgentina/2012/encargadosaula/index.html @@ -26,7 +26,7 @@ Hay 16 bloques disponibles. Una misma persona puede solicitar varios bloques no-simultáneos. Present"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/PyConArgentina/2012/llamadopropuestas/index.html b/PyConArgentina/2012/llamadopropuestas/index.html index cb5c480f2..98d09578e 100644 --- a/PyConArgentina/2012/llamadopropuestas/index.html +++ b/PyConArgentina/2012/llamadopropuestas/index.html @@ -30,7 +30,7 @@ python-es@python.org [MarianoReingart] python-peru@googlegroups"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/PyConArgentina/2012/llamadorevisores/index.html b/PyConArgentina/2012/llamadorevisores/index.html index 1d6fbffbd..5a9cd9774 100644 --- a/PyConArgentina/2012/llamadorevisores/index.html +++ b/PyConArgentina/2012/llamadorevisores/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyConArgentina/2012/llamadosponsors/index.html b/PyConArgentina/2012/llamadosponsors/index.html index e3610d3d5..567c2ee1d 100644 --- a/PyConArgentina/2012/llamadosponsors/index.html +++ b/PyConArgentina/2012/llamadosponsors/index.html @@ -31,7 +31,7 @@ Español: http://ar.pycon.org/2012/sponsors/prospectus?lang=es Inglés: http://ar."> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/PyConArgentina/2012/llamadovoluntarios/index.html b/PyConArgentina/2012/llamadovoluntarios/index.html index 75af2cc81..233761c58 100644 --- a/PyConArgentina/2012/llamadovoluntarios/index.html +++ b/PyConArgentina/2012/llamadovoluntarios/index.html @@ -27,7 +27,7 @@ Encargados de Aula Coordinador de encargados d"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/PyConArgentina/2012/tareaspendientes/index.html b/PyConArgentina/2012/tareaspendientes/index.html index b972ea9cb..7d901c78d 100644 --- a/PyConArgentina/2012/tareaspendientes/index.html +++ b/PyConArgentina/2012/tareaspendientes/index.html @@ -29,7 +29,7 @@ Escribir PyConArgentina/2012/LlamadoSponsors [MarianoReingart] Escribir PyConArgentina/2012/LlamadoPropuestas [MarianoRei"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/PyConArgentina/2012/temaspendientes/index.html b/PyConArgentina/2012/temaspendientes/index.html index d20ead449..3aedd74c8 100644 --- a/PyConArgentina/2012/temaspendientes/index.html +++ b/PyConArgentina/2012/temaspendientes/index.html @@ -29,7 +29,7 @@ --(Escribir LlamamoPropuestas)-- [MarianoReingart] Escribir DocumentoFormal para UNQ: pedido de autorización de aulas, mesas, sillas, c"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/PyConArgentina/2012/transportecompartido/index.html b/PyConArgentina/2012/transportecompartido/index.html index 435ebb989..8aa1b0196 100644 --- a/PyConArgentina/2012/transportecompartido/index.html +++ b/PyConArgentina/2012/transportecompartido/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyConArgentina/2012/workshop/index.html b/PyConArgentina/2012/workshop/index.html index 4a9bbb8c0..df68df42b 100644 --- a/PyConArgentina/2012/workshop/index.html +++ b/PyConArgentina/2012/workshop/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/PyConArgentina/2013/ayuda/index.html b/PyConArgentina/2013/ayuda/index.html index 00469365a..80929aa0f 100644 --- a/PyConArgentina/2013/ayuda/index.html +++ b/PyConArgentina/2013/ayuda/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/PyConArgentina/2013/couchsurfing/index.html b/PyConArgentina/2013/couchsurfing/index.html index 0e2f7f551..1e49c6d3f 100644 --- a/PyConArgentina/2013/couchsurfing/index.html +++ b/PyConArgentina/2013/couchsurfing/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/PyConArgentina/2013/llamadosedes/index.html b/PyConArgentina/2013/llamadosedes/index.html index 84a57d0d1..013c2f2e9 100644 --- a/PyConArgentina/2013/llamadosedes/index.html +++ b/PyConArgentina/2013/llamadosedes/index.html @@ -28,7 +28,7 @@ Mejorar la forma de proponer sedes, con "> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/PyConArgentina/2013/transportsurfing/index.html b/PyConArgentina/2013/transportsurfing/index.html index 0016eb95f..fa04caa0d 100644 --- a/PyConArgentina/2013/transportsurfing/index.html +++ b/PyConArgentina/2013/transportsurfing/index.html @@ -27,7 +27,7 @@ Como funciona? Los Hosts (quienes t"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/PyDay2/callforcharlas/index.html b/PyDay2/callforcharlas/index.html index 1d926f9c1..52694dddc 100644 --- a/PyDay2/callforcharlas/index.html +++ b/PyDay2/callforcharlas/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/RemerasV2/alecu1/index.html b/RemerasV2/alecu1/index.html index 0dfaf4df2..e604dd4d5 100644 --- a/RemerasV2/alecu1/index.html +++ b/RemerasV2/alecu1/index.html @@ -26,7 +26,7 @@ Diseñ"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/RemerasV2/cesarportela1/index.html b/RemerasV2/cesarportela1/index.html index cc44dd673..01addba24 100644 --- a/RemerasV2/cesarportela1/index.html +++ b/RemerasV2/cesarportela1/index.html @@ -29,7 +29,7 @@ Comentarios MarianoMara: ¿podrá ser con el logo de Python (PSF)"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/RemerasV2/cesarroldan1/index.html b/RemerasV2/cesarroldan1/index.html index 2df809ca8..4aa0202de 100644 --- a/RemerasV2/cesarroldan1/index.html +++ b/RemerasV2/cesarroldan1/index.html @@ -30,7 +30,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/cesarroldan2/index.html b/RemerasV2/cesarroldan2/index.html index c057878e1..4bda645d3 100644 --- a/RemerasV2/cesarroldan2/index.html +++ b/RemerasV2/cesarroldan2/index.html @@ -31,7 +31,7 @@ [FacundoBatista] ¡Me gusta! ¿Por qué no en azul? algo que estaría bueno también es ponerle algo como... "Este cuerpo es Python powered", o a'> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/RemerasV2/cesarroldan3/index.html b/RemerasV2/cesarroldan3/index.html index 56ec33f4c..ecaac6285 100644 --- a/RemerasV2/cesarroldan3/index.html +++ b/RemerasV2/cesarroldan3/index.html @@ -32,7 +32,7 @@ [FacundoBatista] Me preocupa el tema de la impresión... ¿se "> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/RemerasV2/facundobatista1/index.html b/RemerasV2/facundobatista1/index.html index 082f87302..06cd34a56 100644 --- a/RemerasV2/facundobatista1/index.html +++ b/RemerasV2/facundobatista1/index.html @@ -30,7 +30,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/facundobatista2/index.html b/RemerasV2/facundobatista2/index.html index 54382e684..ea2995731 100644 --- a/RemerasV2/facundobatista2/index.html +++ b/RemerasV2/facundobatista2/index.html @@ -30,7 +30,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/facundobatista3/index.html b/RemerasV2/facundobatista3/index.html index 125abf078..c2c3efe5f 100644 --- a/RemerasV2/facundobatista3/index.html +++ b/RemerasV2/facundobatista3/index.html @@ -30,7 +30,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/facundobatista4/index.html b/RemerasV2/facundobatista4/index.html index 7af6073ee..12013b30b 100644 --- a/RemerasV2/facundobatista4/index.html +++ b/RemerasV2/facundobatista4/index.html @@ -30,7 +30,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/facundobatista5/index.html b/RemerasV2/facundobatista5/index.html index 839f0a16d..2fd118a04 100644 --- a/RemerasV2/facundobatista5/index.html +++ b/RemerasV2/facundobatista5/index.html @@ -31,7 +31,7 @@ [LucioTorre, en la lista] Sin la URL atrás, pero sí adelante. [FacundoBatista] Sigo esperando los colores, 😉"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/RemerasV2/hernanbalocco1/index.html b/RemerasV2/hernanbalocco1/index.html index 8e4bca0d1..6d9c7d769 100644 --- a/RemerasV2/hernanbalocco1/index.html +++ b/RemerasV2/hernanbalocco1/index.html @@ -30,7 +30,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/humitos1/index.html b/RemerasV2/humitos1/index.html index 7f7772c7d..30a225e96 100644 --- a/RemerasV2/humitos1/index.html +++ b/RemerasV2/humitos1/index.html @@ -33,7 +33,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/RemerasV2/juanjo1/index.html b/RemerasV2/juanjo1/index.html index 1c89992fc..345377652 100644 --- a/RemerasV2/juanjo1/index.html +++ b/RemerasV2/juanjo1/index.html @@ -32,7 +32,7 @@ [FacundoBatista] No me gusta que no diga PyAr en ningún lado... [JuanjoConti] Corregido!"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/RemerasV2/laubenech1/index.html b/RemerasV2/laubenech1/index.html index c7c02de05..6a4616922 100644 --- a/RemerasV2/laubenech1/index.html +++ b/RemerasV2/laubenech1/index.html @@ -30,7 +30,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/laubenech2/index.html b/RemerasV2/laubenech2/index.html index 6bf0a955e..be108a512 100644 --- a/RemerasV2/laubenech2/index.html +++ b/RemerasV2/laubenech2/index.html @@ -31,7 +31,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/RemerasV2/laubenech3/index.html b/RemerasV2/laubenech3/index.html index 1aa5032f2..1e8286d3f 100644 --- a/RemerasV2/laubenech3/index.html +++ b/RemerasV2/laubenech3/index.html @@ -30,7 +30,7 @@ [RicardoKirkner] Hasta ahora una de las mejorcitas que vi. Ahora, haciendo referencia a lo que se charló en la lista, podría ser una variante en "> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/laubenech4/index.html b/RemerasV2/laubenech4/index.html index aa62bf571..1a6634e17 100644 --- a/RemerasV2/laubenech4/index.html +++ b/RemerasV2/laubenech4/index.html @@ -30,7 +30,7 @@ AlejandroJCura: Me encanta esta. Podría ser igual, pero con la boca un poco más cerrada? PD: guarda que el svg tiene dos colores delante y dos de"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/laubenech5/index.html b/RemerasV2/laubenech5/index.html index 7c5ffa2ac..282caca56 100644 --- a/RemerasV2/laubenech5/index.html +++ b/RemerasV2/laubenech5/index.html @@ -30,7 +30,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/laubenech6/index.html b/RemerasV2/laubenech6/index.html index d8bcea99f..b217ab14f 100644 --- a/RemerasV2/laubenech6/index.html +++ b/RemerasV2/laubenech6/index.html @@ -30,7 +30,7 @@ [quien?] (placeholder)"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV2/nubis1/index.html b/RemerasV2/nubis1/index.html index 2c4b6eb99..8a2a63d02 100644 --- a/RemerasV2/nubis1/index.html +++ b/RemerasV2/nubis1/index.html @@ -26,7 +26,7 @@ Unifico las dos propuestas ya que una vez hecho el shablon, es solo un cambio de colores (asi hay para todos los gustos) Hay una version real con una modificacion posible s"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/RemerasV2/nubis2/index.html b/RemerasV2/nubis2/index.html index 336caf82f..8d2f3c597 100644 --- a/RemerasV2/nubis2/index.html +++ b/RemerasV2/nubis2/index.html @@ -28,7 +28,7 @@ Di"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/RemerasV2/pabloziliani1/index.html b/RemerasV2/pabloziliani1/index.html index c8a83eefa..8ff54b233 100644 --- a/RemerasV2/pabloziliani1/index.html +++ b/RemerasV2/pabloziliani1/index.html @@ -27,7 +27,7 @@ Una remera con solpiente Dos versiones, una idea: mantener la identidad reusando la serpiente-sol que tenemos en la bandera. Uso solamente un color. Si alguna palabra no la entiend"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/RemerasV2/pabloziliani2/index.html b/RemerasV2/pabloziliani2/index.html index 1a9689c18..58f8b2823 100644 --- a/RemerasV2/pabloziliani2/index.html +++ b/RemerasV2/pabloziliani2/index.html @@ -27,7 +27,7 @@ Una remera con explicación para personas grandes http://www.franciscorobles.com.ar/libros/principito/pag01.htm Un solo color es suficiente. (nota: la tipografía usada en el svg es "> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/RemerasV2/preanotados/index.html b/RemerasV2/preanotados/index.html index fa49830a1..c8e1d2280 100644 --- a/RemerasV2/preanotados/index.html +++ b/RemerasV2/preanotados/index.html @@ -34,7 +34,7 @@ PabloZiliani 1 XL negra,"> - + Ir al contenido principal @@ -68,12 +68,12 @@ - + diff --git a/RemerasV2/ramiromorales1/index.html b/RemerasV2/ramiromorales1/index.html index 0ecba9764..735cfe3d8 100644 --- a/RemerasV2/ramiromorales1/index.html +++ b/RemerasV2/ramiromorales1/index.html @@ -26,7 +26,7 @@ [RamiroMorales] No me peguen, soy tasteless!..."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/RemerasV2/solounejemplo0/index.html b/RemerasV2/solounejemplo0/index.html index 98bc0352b..7fe6c084d 100644 --- a/RemerasV2/solounejemplo0/index.html +++ b/RemerasV2/solounejemplo0/index.html @@ -30,7 +30,7 @@ [FacundoBat"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/RemerasV3/leonardovidarte1/index.html b/RemerasV3/leonardovidarte1/index.html index 17f78768c..b46c5290f 100644 --- a/RemerasV3/leonardovidarte1/index.html +++ b/RemerasV3/leonardovidarte1/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/RemerasV3/leonardovidarte2/index.html b/RemerasV3/leonardovidarte2/index.html index 9e7df9a67..b37b94539 100644 --- a/RemerasV3/leonardovidarte2/index.html +++ b/RemerasV3/leonardovidarte2/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/RemerasV3/leonardovidarte3/index.html b/RemerasV3/leonardovidarte3/index.html index 96c1d741e..0c19a80aa 100644 --- a/RemerasV3/leonardovidarte3/index.html +++ b/RemerasV3/leonardovidarte3/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/RemerasV3/leonardovidarte4/index.html b/RemerasV3/leonardovidarte4/index.html index 49c32f45c..508dc443c 100644 --- a/RemerasV3/leonardovidarte4/index.html +++ b/RemerasV3/leonardovidarte4/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/RemerasV3/luciotorre1/index.html b/RemerasV3/luciotorre1/index.html index 4d9687661..3ea8c7fea 100644 --- a/RemerasV3/luciotorre1/index.html +++ b/RemerasV3/luciotorre1/index.html @@ -27,7 +27,7 @@ LucioTorre1 (diseño en remera negra) LucioTorre2 (diseño en remera azul)"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/RemerasV3/manuelarguelles1/index.html b/RemerasV3/manuelarguelles1/index.html index 1d3fc3525..96502e2d2 100644 --- a/RemerasV3/manuelarguelles1/index.html +++ b/RemerasV3/manuelarguelles1/index.html @@ -32,7 +32,7 @@ == Comentarios == ..."> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/RemerasV3/manuelarguelles2/index.html b/RemerasV3/manuelarguelles2/index.html index a63eff38a..1e389bef6 100644 --- a/RemerasV3/manuelarguelles2/index.html +++ b/RemerasV3/manuelarguelles2/index.html @@ -32,7 +32,7 @@ == Comentarios == ..."> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/RemerasV3/manuelarguelles3/index.html b/RemerasV3/manuelarguelles3/index.html index 9bee22919..b06a8dd18 100644 --- a/RemerasV3/manuelarguelles3/index.html +++ b/RemerasV3/manuelarguelles3/index.html @@ -28,7 +28,7 @@ == Comentarios == ..."> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/RemerasV3/pedidos/index.html b/RemerasV3/pedidos/index.html index ee54c34c6..15eaaf643 100644 --- a/RemerasV3/pedidos/index.html +++ b/RemerasV3/pedidos/index.html @@ -26,7 +26,7 @@ Pedidos Remeras V3 (diseño del Zen) PyCo"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/RicardoKirkner/labanderadepyar/index.html b/RicardoKirkner/labanderadepyar/index.html index a6914b646..23b5b79a0 100644 --- a/RicardoKirkner/labanderadepyar/index.html +++ b/RicardoKirkner/labanderadepyar/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/RicardoKirkner/miembrosdepyar/index.html b/RicardoKirkner/miembrosdepyar/index.html index 302c05824..223bdf3a6 100644 --- a/RicardoKirkner/miembrosdepyar/index.html +++ b/RicardoKirkner/miembrosdepyar/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/SebastianBassi/codigo1/index.html b/SebastianBassi/codigo1/index.html index 9ab4dc31f..f273b0de3 100644 --- a/SebastianBassi/codigo1/index.html +++ b/SebastianBassi/codigo1/index.html @@ -29,7 +29,7 @@ # leo DB #dbfn = 'allseqs-AR.db' dbfn = '../AS/allseqs-AS.db' conn = sqlite3.connect(dbfn) c = conn.cursor() # CREATE TABLES c.execute("SELECT ctgID,read"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + @@ -88,13 +88,13 @@

    Codigo1

    PRUEBA:

    -
    #!/usr/bin/env python
    -
    -import sqlite3
    -
    -# leo DB #dbfn = 'allseqs-AR.db' dbfn = '../AS/allseqs-AS.db' conn = sqlite3.connect(dbfn) c = conn.cursor() # CREATE TABLES c.execute("SELECT ctgID,read from ctgs") for row in c:
    -
    -ctg = row[0] lib = row[1].split('-')[0][-3:]
    +
    #!/usr/bin/env python
    +
    +import sqlite3
    +
    +# leo DB #dbfn = 'allseqs-AR.db' dbfn = '../AS/allseqs-AS.db' conn = sqlite3.connect(dbfn) c = conn.cursor() # CREATE TABLES c.execute("SELECT ctgID,read from ctgs") for row in c:
    +
    +ctg = row[0] lib = row[1].split('-')[0][-3:]
     

    klkl

    diff --git a/SebastianBassi/codigo2/index.html b/SebastianBassi/codigo2/index.html index f492a53ac..fc6c3baf5 100644 --- a/SebastianBassi/codigo2/index.html +++ b/SebastianBassi/codigo2/index.html @@ -34,7 +34,7 @@ c.execute("SELECT ctgID,read from ctgs") for r"> - + Ir al contenido principal @@ -68,12 +68,12 @@ - +
    @@ -93,19 +93,19 @@

    Codigo2

    Otra prueba:

    -
    import sqlite3
    -
    -# leo DB
    -#dbfn = 'allseqs-AR.db'
    -dbfn = '../AS/allseqs-AS.db'
    -conn = sqlite3.connect(dbfn)
    -c = conn.cursor()
    -# CREATE TABLES
    -c.execute("SELECT ctgID,read from ctgs")
    -for row in c:
    -    ctg = row[0]
    -    lib = row[1].split('-')[0][-3:]
    -    #break
    +
    import sqlite3
    +
    +# leo DB
    +#dbfn = 'allseqs-AR.db'
    +dbfn = '../AS/allseqs-AS.db'
    +conn = sqlite3.connect(dbfn)
    +c = conn.cursor()
    +# CREATE TABLES
    +c.execute("SELECT ctgID,read from ctgs")
    +for row in c:
    +    ctg = row[0]
    +    lib = row[1].split('-')[0][-3:]
    +    #break
     

    FIN de prueba.

    diff --git a/ServidorPyAr/scsi/index.html b/ServidorPyAr/scsi/index.html index ea7e4d101..b1de5b5d8 100644 --- a/ServidorPyAr/scsi/index.html +++ b/ServidorPyAr/scsi/index.html @@ -28,7 +28,7 @@ http://tinyurl.com/6ou4dr <=== Tengo cuenta en ebay, "> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    diff --git a/TareasPendientes/tareasrealizadas/index.html b/TareasPendientes/tareasrealizadas/index.html index 435bf3795..2ba17db81 100644 --- a/TareasPendientes/tareasrealizadas/index.html +++ b/TareasPendientes/tareasrealizadas/index.html @@ -32,7 +32,7 @@ Dar de alta "> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/ToDo/tareasrealizadas/index.html b/ToDo/tareasrealizadas/index.html index d1406a5cf..c216a8929 100644 --- a/ToDo/tareasrealizadas/index.html +++ b/ToDo/tareasrealizadas/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/Videohttp/pyaruslaorgar/orm001ogv/index.html b/Videohttp/pyaruslaorgar/orm001ogv/index.html index 9bc1853ca..d2276c8e9 100644 --- a/Videohttp/pyaruslaorgar/orm001ogv/index.html +++ b/Videohttp/pyaruslaorgar/orm001ogv/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/aafigure/index.html b/aafigure/index.html index 5bdda7f80..246422f3f 100644 --- a/aafigure/index.html +++ b/aafigure/index.html @@ -28,7 +28,7 @@ El nombre del parser es {{{aafig}}} y las opciones se agregan separadas por espacios. Las opciones que requieren valores los toman luego d"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/aafigure/test/index.html b/aafigure/test/index.html index 587229298..7a0e14252 100644 --- a/aafigure/test/index.html +++ b/aafigure/test/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/actividades/index.html b/actividades/index.html index cb1b7df79..4c26bf869 100644 --- a/actividades/index.html +++ b/actividades/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/admin/index.html b/admin/index.html index 7e0f176fa..28f6fbd2f 100644 --- a/admin/index.html +++ b/admin/index.html @@ -28,7 +28,7 @@ Dominios"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/admingroup/index.html b/admingroup/index.html index dc5febc3a..650d50863 100644 --- a/admingroup/index.html +++ b/admingroup/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/adoptaunnewbie/index.html b/adoptaunnewbie/index.html index bd88f969d..4d33ca906 100644 --- a/adoptaunnewbie/index.html +++ b/adoptaunnewbie/index.html @@ -26,7 +26,7 @@ que está buscando aprender de algo en particular, encuentre y se conecte con gente que está dispuesta a mentorear en esos"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/adrianpardini/index.html b/adrianpardini/index.html index ec3b658ff..2714e1b8f 100644 --- a/adrianpardini/index.html +++ b/adrianpardini/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/afichepyconar2011/index.html b/afichepyconar2011/index.html index 21afd8dd1..ebec2bac0 100644 --- a/afichepyconar2011/index.html +++ b/afichepyconar2011/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/alberto-pastor/index.html b/alberto-pastor/index.html index 3b149b9ac..0fee561ba 100644 --- a/alberto-pastor/index.html +++ b/alberto-pastor/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/albertopaparelli/index.html b/albertopaparelli/index.html index af2e14a58..fffa78f0b 100644 --- a/albertopaparelli/index.html +++ b/albertopaparelli/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/alecutest2/index.html b/alecutest2/index.html index c05b2bc71..e7867314a 100644 --- a/alecutest2/index.html +++ b/alecutest2/index.html @@ -26,7 +26,7 @@ Email: you AT SPAMFREE example DOT com You can even more obfuscate your email address by adding more uppercase letters followed by a leading and trailing blank. ..."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/alejandrodavidweil/index.html b/alejandrodavidweil/index.html index f4fbd1151..0ed6451f0 100644 --- a/alejandrodavidweil/index.html +++ b/alejandrodavidweil/index.html @@ -26,7 +26,7 @@ Programo en Python desde, aproximadamente, el 2004. La página Audio incluye varioas grabaciones de charlas acerca de python, es un link interesante."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/alejandrojcura/index.html b/alejandrojcura/index.html index f18ebd4a6..f08dc8169 100644 --- a/alejandrojcura/index.html +++ b/alejandrojcura/index.html @@ -29,7 +29,7 @@ ahora uso: buildbot, selenium, django. Uso y me aburr"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/alejandrosantos/index.html b/alejandrosantos/index.html index fe6fccb8f..347c780b6 100644 --- a/alejandrosantos/index.html +++ b/alejandrosantos/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/alejopagadizabal/index.html b/alejopagadizabal/index.html index e5d0a8296..a1a62f9f3 100644 --- a/alejopagadizabal/index.html +++ b/alejopagadizabal/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/alfonsopalomares/index.html b/alfonsopalomares/index.html index 6b6bf4010..8591fbede 100644 --- a/alfonsopalomares/index.html +++ b/alfonsopalomares/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/alojamientowebpython/index.html b/alojamientowebpython/index.html index b37698417..d97ba9d7c 100644 --- a/alojamientowebpython/index.html +++ b/alojamientowebpython/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/angelfreire/index.html b/angelfreire/index.html index b793246e2..29c213e12 100644 --- a/angelfreire/index.html +++ b/angelfreire/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/angelvelasquez/index.html b/angelvelasquez/index.html index 97945cf0a..4400317c3 100644 --- a/angelvelasquez/index.html +++ b/angelvelasquez/index.html @@ -27,7 +27,7 @@ twitter: http://twitter.com/angvp linkedin: https://www.linkedin.com/in/angvp"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/anthonylenton/index.html b/anthonylenton/index.html index 691673b00..294f31ea6 100644 --- a/anthonylenton/index.html +++ b/anthonylenton/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/aprendiendopython/index.html b/aprendiendopython/index.html index 9c0a3da9c..a5b383215 100644 --- a/aprendiendopython/index.html +++ b/aprendiendopython/index.html @@ -26,7 +26,7 @@ Antes que nada ¡FELICITACIONES! Ahora ¿A dónde podrías recurrir para obtener información que te inicie en la programación pythonesca? Bueno, estos son algunos libros que se pr"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/archive.html b/archive.html index 1b7c23283..7acc7866b 100644 --- a/archive.html +++ b/archive.html @@ -53,12 +53,12 @@ - + diff --git a/ariel-alvarez/index.html b/ariel-alvarez/index.html index c8a1d6e5d..16bf20c40 100644 --- a/ariel-alvarez/index.html +++ b/ariel-alvarez/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/ariel-barrios/index.html b/ariel-barrios/index.html index 028f078b0..6607cd78d 100644 --- a/ariel-barrios/index.html +++ b/ariel-barrios/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/arturoeanton/index.html b/arturoeanton/index.html index 30ea63721..106c68017 100644 --- a/arturoeanton/index.html +++ b/arturoeanton/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/asociacioncivil/index.html b/asociacioncivil/index.html index e8e0eac98..4268908e7 100644 --- a/asociacioncivil/index.html +++ b/asociacioncivil/index.html @@ -26,7 +26,7 @@ Durante el 2014 se empezó a empujar en serio la idea de que Python Argentina sea una Asociación Civil. Estamos discutiendo todo en esta lista de correo."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/ayudadecontenidospy/index.html b/ayudadecontenidospy/index.html index c1064f4fd..c2a780210 100644 --- a/ayudadecontenidospy/index.html +++ b/ayudadecontenidospy/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/badcontent/index.html b/badcontent/index.html index 71545b33f..5141dd79f 100644 --- a/badcontent/index.html +++ b/badcontent/index.html @@ -27,7 +27,7 @@ (buy)[\w\-_.]*online[\w\-_.]*\.[a-z]{2,} (gambling|porn|\bsms|busty|prescription|pharmacy|penis|pills|enlarge)[\w\-_.]*\.[a"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/bandera/index.html b/bandera/index.html index d7fb1c921..7cd85d1c1 100644 --- a/bandera/index.html +++ b/bandera/index.html @@ -28,7 +28,7 @@ Necesitamos una bandera con el logo de PyAr, para promocionarnos en charlas y conferencias. Vamos a mandar imprimir una bandera gigante de Lona de ent"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/becaspyconar2011/index.html b/becaspyconar2011/index.html index 7f60815f7..bc634b19d 100644 --- a/becaspyconar2011/index.html +++ b/becaspyconar2011/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/blog/index.html b/blog/index.html index dc2334802..2a24c486b 100644 --- a/blog/index.html +++ b/blog/index.html @@ -53,12 +53,12 @@ - + diff --git a/brygevel/index.html b/brygevel/index.html index bf52a472b..c9cc74a0c 100644 --- a/brygevel/index.html +++ b/brygevel/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/buscandogente/index.html b/buscandogente/index.html index c264581fe..cb90b0c88 100644 --- a/buscandogente/index.html +++ b/buscandogente/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/buzospyar/index.html b/buzospyar/index.html index 30ab9bfb9..4ac7aa08d 100644 --- a/buzospyar/index.html +++ b/buzospyar/index.html @@ -26,7 +26,7 @@ Vamos a hacer buzos de Python Argentina!. ¿ Las razones ?, juntar dinero para PyAr, y que podamos tener un espectacular buzo de Python Argentina!!. Los buzos son de tela de "> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/cafeconf2006/index.html b/cafeconf2006/index.html index 97b0ba8c8..f27a6c409 100644 --- a/cafeconf2006/index.html +++ b/cafeconf2006/index.html @@ -36,7 +36,7 @@ alecu todo "> - + Ir al contenido principal @@ -70,12 +70,12 @@ - + diff --git a/callforcharlas/index.html b/callforcharlas/index.html index b60a2bc92..6e57ac967 100644 --- a/callforcharlas/index.html +++ b/callforcharlas/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/callforcharlasinvitaciontemplate/index.html b/callforcharlasinvitaciontemplate/index.html index 7432b03c6..05dc6cc60 100644 --- a/callforcharlasinvitaciontemplate/index.html +++ b/callforcharlasinvitaciontemplate/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/callforcharlastemplate/index.html b/callforcharlastemplate/index.html index 839b15638..ba1d3ac20 100644 --- a/callforcharlastemplate/index.html +++ b/callforcharlastemplate/index.html @@ -26,7 +26,7 @@ PyCon Argentina ANIO – URL CONFNUM Conferencia Argentina de Python FECHA LUGAR PyAr, el Grupo de Usuarios de Python de Argentina invita a toda la comunidad de usuarios de Pytho"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/categories/index.html b/categories/index.html index 3934fc0c2..bd61f33cb 100644 --- a/categories/index.html +++ b/categories/index.html @@ -53,12 +53,12 @@ - + diff --git a/categorycategory/index.html b/categorycategory/index.html index 73caba0b4..544795d2c 100644 --- a/categorycategory/index.html +++ b/categorycategory/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/caucho/index.html b/caucho/index.html index 3663d2c08..a143f8b9a 100644 --- a/caucho/index.html +++ b/caucho/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/cdpedia-on-android/index.html b/cdpedia-on-android/index.html index 12c2456d2..57a6fb5e8 100644 --- a/cdpedia-on-android/index.html +++ b/cdpedia-on-android/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -85,10 +85,10 @@

    Cdpedia On Android

    Cdpedia-on-android es una aplicación android que permite correr la Cdpedia en este sistema operativo.

    Para que funcione correctamente es necesario tener descomprimido (no soporta el archivo .iso) alguno de los releases de la cdpedia en la carpeta /mnt/sdcard/cdpedia. A continuación una mini receta:

    -
    mount -t iso9660 -o loop cdpedia-0.8-cd.iso /mnt
    -cp -R /mnt/cdpedia /media/android_sdcard
    -sync
    -umount /mnt
    +
    mount -t iso9660 -o loop cdpedia-0.8-cd.iso /mnt
    +cp -R /mnt/cdpedia /media/android_sdcard
    +sync
    +umount /mnt
     

    Si querés probar la primera versión de la aplicación para android, podés descargarte el .apk desde acá.

    diff --git a/cfcpyconar2011/index.html b/cfcpyconar2011/index.html index 9d9a9af8a..6f528bb70 100644 --- a/cfcpyconar2011/index.html +++ b/cfcpyconar2011/index.html @@ -31,7 +31,7 @@ Universidad Nacional del Noroeste de la Provincia de Buenos Aires PyAr, el Grupo de Usuarios "> - + Ir al contenido principal @@ -65,12 +65,12 @@ - +
    diff --git a/charlas/index.html b/charlas/index.html index af1f1fa6f..0879cb6ac 100644 --- a/charlas/index.html +++ b/charlas/index.html @@ -35,7 +35,7 @@ Un juego en 7 días Introducción a Py"> - + Ir al contenido principal @@ -69,12 +69,12 @@ - +
    diff --git a/charlasabiertas2010/index.html b/charlasabiertas2010/index.html index d199fbdac..a39a6d741 100644 --- a/charlasabiertas2010/index.html +++ b/charlasabiertas2010/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/cherrypy/index.html b/cherrypy/index.html index 320850d1c..f7ecc9d82 100644 --- a/cherrypy/index.html +++ b/cherrypy/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/chistes/index.html b/chistes/index.html index 39b3524a1..9a62fc856 100644 --- a/chistes/index.html +++ b/chistes/index.html @@ -32,7 +32,7 @@ > Por la poca experiencia que tengo en tg,"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/circoerrante/index.html b/circoerrante/index.html index c620289a2..922052c2d 100644 --- a/circoerrante/index.html +++ b/circoerrante/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/clasesdepython/index.html b/clasesdepython/index.html index d25d7bb7f..ef4c65262 100644 --- a/clasesdepython/index.html +++ b/clasesdepython/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/colaborandoenelwiki/index.html b/colaborandoenelwiki/index.html index a18519075..f61692855 100644 --- a/colaborandoenelwiki/index.html +++ b/colaborandoenelwiki/index.html @@ -39,7 +39,7 @@ rep"> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/colectadehardware/index.html b/colectadehardware/index.html index 05352e44d..dde831add 100644 --- a/colectadehardware/index.html +++ b/colectadehardware/index.html @@ -28,7 +28,7 @@ Show me the SILICONNN!!! Cortita y al pie, en usla nos ofrecieron housing y la verdad que nos hace falta una maquina para meter todos nuestro"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/common_links/index.html b/common_links/index.html index ee62df02e..c0a45559f 100644 --- a/common_links/index.html +++ b/common_links/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/compilarpython/index.html b/compilarpython/index.html index 5a86ed6e4..e41c3ec94 100644 --- a/compilarpython/index.html +++ b/compilarpython/index.html @@ -27,7 +27,7 @@ Compilando Py3k Para compilar primero tenemos que descargar las fuentes desde el repositorio. Para eso, debemos tener un clie"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + @@ -89,7 +89,7 @@

    Compilarpython

    Compilando Py3k

    Para compilar primero tenemos que descargar las fuentes desde el repositorio. Para eso, debemos tener un cliente de subversion ("sudo aptitude install subversion" en linux basados en debian)

    el comando que hay que correr es el siguiente

    -
    svn co http://svn.python.org/projects/python/branches/py3k/
    +
    svn co http://svn.python.org/projects/python/branches/py3k/
     

    luego debemos tener instalados los archivos de desarrollo para poder tener habilitados algunos módulos de Python; si no los instalamos, esos módulos no van a estar disponibles.

    La lista con los nombres en linux basados en debian es:

    @@ -106,47 +106,47 @@

    Compilarpython

  • libdb-dev

  • Luego de instalar todas las librerías debemos correr los siguientes comandos:

    -
    cd py3k
    -./configure
    -make
    -sudo make install
    +
    cd py3k
    +./configure
    +make
    +sudo make install
     

    Si todo salió bien, ahora podemos usar python 3.

    Podemos probar corriendo el comando python3.0 en la consola:

    -
    mariano@mousehouse:~/Software/py3k$ python3.0
    -Python 3.0rc1+ (py3k:66685, Sep 29 2008, 17:25:48)
    -[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
    -Type "help", "copyright", "credits" or "license" for more information.
    ->>>
    +
    mariano@mousehouse:~/Software/py3k$ python3.0
    +Python 3.0rc1+ (py3k:66685, Sep 29 2008, 17:25:48)
    +[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
    +Type "help", "copyright", "credits" or "license" for more information.
    +>>>
     

    Cada vez que queramos actualizar al código más nuevo en el repositorio, debemos hacer lo siguiente:

    -
    cd py3k
    -svn up
    -make
    -sudo make install
    +
    cd py3k
    +svn up
    +make
    +sudo make install
     

    Cómo armar un paquete DEB de Python

    A veces es necesario armar un paquete para facilitar la instalación/desinstalación y pruebas en distintas máquinas.

    Aquí un ejemplo de cómo hacerlo para Debian o Ubuntu (bajando py3k):

    Bajamos y descomprimimos (en este caso, por SVN):

    -
    svn co http://svn.python.org/projects/python/branches/py3k py3k
    -cd py3k
    +
    svn co http://svn.python.org/projects/python/branches/py3k py3k
    +cd py3k
     

    Configuramos y armamos el paquete:

    -
    ./configure --prefix=$HOME
    -cat << EOF > description-pak
    -Python 3.x provisional test package
    -EOF
    -checkinstall -y --pkgname=py3k --pkglicense=PL \
    -             --maintainer=reingart@example.com \
    -             --requires= \
    -             --provides=py3k --pkgrelease=1 \
    -             --pkgsource=http://www.python.org/download/ \
    -             --install=no --reset-uids=yes \
    -             -D make install
    +
    ./configure --prefix=$HOME
    +cat << EOF > description-pak
    +Python 3.x provisional test package
    +EOF
    +checkinstall -y --pkgname=py3k --pkglicense=PL \
    +             --maintainer=reingart@example.com \
    +             --requires= \
    +             --provides=py3k --pkgrelease=1 \
    +             --pkgsource=http://www.python.org/download/ \
    +             --install=no --reset-uids=yes \
    +             -D make install
     

    Luego, instalamos el paquete con:

    -
    dpkg -i py3k-1_i386.deb
    +
    dpkg -i py3k-1_i386.deb
     
    diff --git a/condornet/index.html b/condornet/index.html index bb08098dd..72c163294 100644 --- a/condornet/index.html +++ b/condornet/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/contribuyendoalwiki/index.html b/contribuyendoalwiki/index.html index fd0cfc26a..965943cdb 100644 --- a/contribuyendoalwiki/index.html +++ b/contribuyendoalwiki/index.html @@ -26,7 +26,7 @@ falta que sea un usuario registrado de la web. Hay algunas páginas especiales que sólo pueden "> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/cristianskalican/index.html b/cristianskalican/index.html index f378f1257..9a6c4ac7b 100644 --- a/cristianskalican/index.html +++ b/cristianskalican/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/cronogramapyconar2011/index.html b/cronogramapyconar2011/index.html index b77434748..1afa13449 100644 --- a/cronogramapyconar2011/index.html +++ b/cronogramapyconar2011/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/danielmendoza/index.html b/danielmendoza/index.html index 4078f803b..4b154e3fa 100644 --- a/danielmendoza/index.html +++ b/danielmendoza/index.html @@ -28,7 +28,7 @@ Hola a todas, describire brevemente mi persona, o algunas actividades que realizo. Soy Analista Universitario en Sistemas de Infor"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/danielmoisset/index.html b/danielmoisset/index.html index abc92f4e2..cdff307cd 100644 --- a/danielmoisset/index.html +++ b/danielmoisset/index.html @@ -27,7 +27,7 @@ LinkedIn: http://ar.linkedin.com/in/dmoisset Mi empresa (donde obviamente usamos mayoritariamente python): http://www.machinalis.com"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/davidlitvak/index.html b/davidlitvak/index.html index 07768fa1c..6684f1525 100644 --- a/davidlitvak/index.html +++ b/davidlitvak/index.html @@ -26,7 +26,7 @@ ... Desarrollador de Crawle"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/dbapi/index.html b/dbapi/index.html index 4f8e54ab8..8c94414ef 100644 --- a/dbapi/index.html +++ b/dbapi/index.html @@ -31,7 +31,7 @@ En python, el acceso a bases de datos esta estandarizado por la especificac"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + @@ -109,95 +109,95 @@

    Acceso A Bases De Datos Desde Python: Interfaz Db-Api


    ¿Cómo me conecto a una base de datos con MySQL?

    Este es un ejemplo basico de como hacerlo con MySQL:

    -
    >>> import MySQLdb
    ->>> db = MySQLdb.connect(host="localhost", user="root",
    -... passwd="mypassword", db="PythonU")
    +
    >>> import MySQLdb
    +>>> db = MySQLdb.connect(host="localhost", user="root",
    +... passwd="mypassword", db="PythonU")
     

    Una vez establecida la conexion, hay que crear un "cursor". Un cursor es una estructura de control que se usa para recorrer (y eventualmente procesar) los records de un result set.

    El metodo para crear el cursor se llama, originalmente, cursor():

    -
    >>> cursor = db.cursor()
    +
    >>> cursor = db.cursor()
     

    Ya tenemos la conexion establecida y el cursor creado, es hora de ejecutar algunos comandos SQL:

    -
    >>> cursor.execute("SELECT * FROM Students")
    -5L
    +
    >>> cursor.execute("SELECT * FROM Students")
    +5L
     

    El metodo execute se usa para ejecutar comandos SQL. Note que no hace falta agregar el ';' (punto y coma) al final del comando. Ahora es cuestion de recorrer el objeto cursor.

    Para obtener un solo elemento, usamos fetchone():

    -
    >>> cursor.fetchone()
    -(1L, 'Joe', 'Campbell', datetime.date(2006, 2, 10), 'N')
    -
    ->>> cursor.fetchall()
    -((1L, 'Joe', 'Campbell', datetime.date(2006, 2, 10), 'N'),
    -(2L, 'Joe', 'Doe', datetime.date(2004, 2, 16), 'N'),
    -(3L, 'Rick', 'Hunter', datetime.date(2005, 3, 20), 'N'),
    -(4L, 'Laura', 'Ingalls', datetime.date(2001, 3, 15), 'Y'),
    -(5L, 'Virginia', 'Gonzalez', datetime.date(2003, 4, 2), 'N'))
    +
    >>> cursor.fetchone()
    +(1L, 'Joe', 'Campbell', datetime.date(2006, 2, 10), 'N')
    +
    +>>> cursor.fetchall()
    +((1L, 'Joe', 'Campbell', datetime.date(2006, 2, 10), 'N'),
    +(2L, 'Joe', 'Doe', datetime.date(2004, 2, 16), 'N'),
    +(3L, 'Rick', 'Hunter', datetime.date(2005, 3, 20), 'N'),
    +(4L, 'Laura', 'Ingalls', datetime.date(2001, 3, 15), 'Y'),
    +(5L, 'Virginia', 'Gonzalez', datetime.date(2003, 4, 2), 'N'))
     

    Cual metodo usar dependera de la cantidad de datos que tengamos, la memoria disponible en la PC y sobre todo, de como querramos hacerlo. Si estamos trabajando con datasets limitados, no habra problema con el uso de fetchall(), pero si la base de datos es lo suficientemente grande como para entrar en memoria, se podria implementar una estrategia como la que se encuentra aca:

    -
    import MySQLdb
    -db = MySQLdb.connect(host="localhost", user="root",passwd="secret", db="PythonU")
    -cursor = db.cursor()
    -recs=cursor.execute("SELECT * FROM Students")
    -for x in range(recs):
    -   print cursor.fetchone()
    +
    import MySQLdb
    +db = MySQLdb.connect(host="localhost", user="root",passwd="secret", db="PythonU")
    +cursor = db.cursor()
    +recs=cursor.execute("SELECT * FROM Students")
    +for x in range(recs):
    +   print cursor.fetchone()
     

    O directamente:

    -
    import MySQLdb
    -db = MySQLdb.connect(host="localhost", user="root",passwd="secret", db="PythonU")
    -cursor = db.cursor()
    -cursor.execute("SELECT * FROM Students")
    -for row in cursor:
    -   print row
    +
    import MySQLdb
    +db = MySQLdb.connect(host="localhost", user="root",passwd="secret", db="PythonU")
    +cursor = db.cursor()
    +cursor.execute("SELECT * FROM Students")
    +for row in cursor:
    +   print row
     

    (Sebastian Bassi)


    ¿Cómo me conecto a una base de datos con PostgreSQL?

    Otro ejemplo basico de como hacerlo con PostgreSQL (similar al de MySQL). Se usó el esquema: CREATE TABLE estudiante ( nombre varchar,  apellido varchar,  fecha date,  booleano bool,  legajo serial PRIMARY KEY); Antes que nada se debe instalar el conector (para unix y windows).

    Primero importar el conector y crear la conexión a la base de datos:

    -
    >>> import psycopg2, psycopg2.extras
    ->>> conn = psycopg2.connect(database='test',user='postgres',password='pass', host='localhost')
    +
    >>> import psycopg2, psycopg2.extras
    +>>> conn = psycopg2.connect(database='test',user='postgres',password='pass', host='localhost')
     

    Luego crear un cursor para obtener los datos y ejecutar consulta:

    -
    >>> cur = conn.cursor()
    ->>> cur.execute("SELECT * FROM estudiante")
    ->>> rows=cur.fetchall()
    ->>> print rows
    -
    -[['Joe', 'Capbell', datetime.date(2006, 2, 10), False, 1], ['Joe', 'Doe', datetime.date(2004, 2, 16), False, 2], ['Rick', 'Hunter', datetime.date(2005, 3, 20), False, 3], ['Laura', 'Ingalls', datetime.date(2001, 3, 15), True, 4], ['Virginia', 'Gonzalez', datetime.date(2003, 4, 2), False, 5]]
    +
    >>> cur = conn.cursor()
    +>>> cur.execute("SELECT * FROM estudiante")
    +>>> rows=cur.fetchall()
    +>>> print rows
    +
    +[['Joe', 'Capbell', datetime.date(2006, 2, 10), False, 1], ['Joe', 'Doe', datetime.date(2004, 2, 16), False, 2], ['Rick', 'Hunter', datetime.date(2005, 3, 20), False, 3], ['Laura', 'Ingalls', datetime.date(2001, 3, 15), True, 4], ['Virginia', 'Gonzalez', datetime.date(2003, 4, 2), False, 5]]
     

    Algo más pitónico es crear el cursor simil diccionario (en vez de una lista de valores):

    -
    >>> cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    ->>> cur.execute("SELECT * FROM estudiante")
    ->>> for row in cur: # itero sober cada fila
    ->>>    # row es un diccionario, con las claves = nombres de campos
    ->>>    print "Nombre y Apellido: %s, %s " % (row['nombre'],row['apellido'])
    -
    -Nombre y Apellido: Joe, Capbell
    -Nombre y Apellido: Joe, Doe
    -Nombre y Apellido: Rick, Hunter
    -Nombre y Apellido: Laura, Ingalls
    -Nombre y Apellido: Virginia, Gonzalez
    +
    >>> cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    +>>> cur.execute("SELECT * FROM estudiante")
    +>>> for row in cur: # itero sober cada fila
    +>>>    # row es un diccionario, con las claves = nombres de campos
    +>>>    print "Nombre y Apellido: %s, %s " % (row['nombre'],row['apellido'])
    +
    +Nombre y Apellido: Joe, Capbell
    +Nombre y Apellido: Joe, Doe
    +Nombre y Apellido: Rick, Hunter
    +Nombre y Apellido: Laura, Ingalls
    +Nombre y Apellido: Virginia, Gonzalez
     

    Nota: esto es propio del conector psycopg2. Igualmente otros conectores tambien lo soportan o se puede imitar (leyendo el atributo description del cursor que tiene la información de los campos):

    -
    >>> print cur.description
    -(('nombre', 1043, 8, -1, None, None, None), ('apellido', 1043, 8, -1, None, None, None), ('fecha', 1082, 10, 4, None, None, None), ('booleano', 16, 1, 1, None, None, None), ('legajo', 23, 1, 4, None, None, None))
    +
    >>> print cur.description
    +(('nombre', 1043, 8, -1, None, None, None), ('apellido', 1043, 8, -1, None, None, None), ('fecha', 1082, 10, 4, None, None, None), ('booleano', 16, 1, 1, None, None, None), ('legajo', 23, 1, 4, None, None, None))
     

    Parámetros

    Pregunta: Hola chicos. Estoy con un inconveniente que no puedo solventar. Tengo una funcion de python que genera unos querystrings para postgres.

    Mi problema empieza cuando, por ejemplo hay uno de esos apellidos que tienen ', Ej: D'agostino

    como resultado me queda el string (ejemplo)

    -
    'insert into personas (apellido) values ("D'agostino")'
    +
    'insert into personas (apellido) values ("D'agostino")'
     

    Respuesta:

    Lo que tendrías que hacer es que postgres te escapee automaticamente los valores, usando los parámetros de db-api (segúndo argumento del metodo execute del cursor):

    -
    cur = conn.cursor()
    -cur.execute("insert into personas (apellido) values (%s)" , ["D'agostino"])
    +
    cur = conn.cursor()
    +cur.execute("insert into personas (apellido) values (%s)" , ["D'agostino"])
     

    Así, automáticamente postgres sabe, según el tipo de datos del parámetro, en este caso un string = "D'agostino", como escapear y formatear el sql para que no de error.

    Además, esto es mas seguro frente a ataques por "inyección de sql", porque el formateo es automático, en vez de usar directamente el operador % sobre el query y pasarselo cocinado a la base.

    Para hacerlo más robusto, podrías usar diccionario con los parametros (es más seguro en el caso que tengas varios parámetros, para evitar errores):

    -
    cur.execute("insert into personas (apellido) values (%(apellido)s)" , {"apellido":"D'agostino"})
    +
    cur.execute("insert into personas (apellido) values (%(apellido)s)" , {"apellido":"D'agostino"})
     

    Igualmente, esto dependerá de las capacidades de cada conector (consultar variable paramstyle del módulo conector), pudiendo utilizarse los siguientes estilos de parametros:

      diff --git a/deretiroacordoba/index.html b/deretiroacordoba/index.html index 822bcbd17..b73e57e08 100644 --- a/deretiroacordoba/index.html +++ b/deretiroacordoba/index.html @@ -54,7 +54,7 @@ h"> - + Ir al contenido principal @@ -88,12 +88,12 @@ - +
    diff --git a/desarrollador-jr-o-ssr-django-y-javascript/index.html b/desarrollador-jr-o-ssr-django-y-javascript/index.html index 58b75cd41..2878b5415 100644 --- a/desarrollador-jr-o-ssr-django-y-javascript/index.html +++ b/desarrollador-jr-o-ssr-django-y-javascript/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    diff --git a/diegoahumada/index.html b/diegoahumada/index.html index 2150320d4..793faceb4 100644 --- a/diegoahumada/index.html +++ b/diegoahumada/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    diff --git a/diegosarmentero/index.html b/diegosarmentero/index.html index 9fe13fe6c..d53e557e8 100644 --- a/diegosarmentero/index.html +++ b/diegosarmentero/index.html @@ -27,7 +27,7 @@ Pagina Personal: http://diegosarm'> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/dieresys/index.html b/dieresys/index.html index 7d7a12152..8a8dda871 100644 --- a/dieresys/index.html +++ b/dieresys/index.html @@ -29,7 +29,7 @@ Matches: from:(enri57ar(AT)gmail.com) Do this: Skip Inbox, Delete it ..."> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/distutils/index.html b/distutils/index.html index d7c65a6cc..1b17b501a 100644 --- a/distutils/index.html +++ b/distutils/index.html @@ -26,7 +26,7 @@ import py2exe setup(console=['hola.py'])"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/diversidad/index.html b/diversidad/index.html index 32fb9b4ea..c879d3a7a 100644 --- a/diversidad/index.html +++ b/diversidad/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/edupython/index.html b/edupython/index.html index 86f57f3f7..b378ed786 100644 --- a/edupython/index.html +++ b/edupython/index.html @@ -30,7 +30,7 @@ "Recordad que para poder modificar la wiki y po'> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/edupythoncd/index.html b/edupythoncd/index.html index 521c04b27..55a1b37ef 100644 --- a/edupythoncd/index.html +++ b/edupythoncd/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/ejercicios/index.html b/ejercicios/index.html index 68053583c..5d9b4f3a9 100644 --- a/ejercicios/index.html +++ b/ejercicios/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/elisabeth-hartwig/index.html b/elisabeth-hartwig/index.html index be01686f6..4a9c4c7df 100644 --- a/elisabeth-hartwig/index.html +++ b/elisabeth-hartwig/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eloycolell/index.html b/eloycolell/index.html index 5ad28d065..51bedde7e 100644 --- a/eloycolell/index.html +++ b/eloycolell/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/emilianodallaverdemarcozzi/index.html b/emilianodallaverdemarcozzi/index.html index 928c8e107..1a9da259b 100644 --- a/emilianodallaverdemarcozzi/index.html +++ b/emilianodallaverdemarcozzi/index.html @@ -27,7 +27,7 @@ Un poco sobre mi: En el 2007 conocí Pyth"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/emilioramirez/index.html b/emilioramirez/index.html index 3944eb49e..82974fdda 100644 --- a/emilioramirez/index.html +++ b/emilioramirez/index.html @@ -33,7 +33,7 @@ email: emilioramirez04@gmail.com linkedin: emil"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/empresasyprofesionales/index.html b/empresasyprofesionales/index.html index 766f98408..18bdd7691 100644 --- a/empresasyprofesionales/index.html +++ b/empresasyprofesionales/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/enlosmedios/index.html b/enlosmedios/index.html index c181b2237..3670aece8 100644 --- a/enlosmedios/index.html +++ b/enlosmedios/index.html @@ -26,7 +26,7 @@ Reportaje sobre CDPedia a Facundo Batista FM La Tribu, 20 Enero 2010. Juegos en el iPhone con sello nac"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/etiquetapyar/index.html b/etiquetapyar/index.html index 5201f506b..b25783ee1 100644 --- a/etiquetapyar/index.html +++ b/etiquetapyar/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eugeniabahit/index.html b/eugeniabahit/index.html index 3b3abfc69..1bdcc0964 100644 --- a/eugeniabahit/index.html +++ b/eugeniabahit/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/2016/reunion66/index.html b/eventos/2016/reunion66/index.html index ae61bc8c7..1bbe90ea1 100644 --- a/eventos/2016/reunion66/index.html +++ b/eventos/2016/reunion66/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Conferencias/2jornadapythonstafe/index.html b/eventos/Conferencias/2jornadapythonstafe/index.html index 60da55007..287ba954f 100644 --- a/eventos/Conferencias/2jornadapythonstafe/index.html +++ b/eventos/Conferencias/2jornadapythonstafe/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/Conferencias/8JRSL/carteles/index.html b/eventos/Conferencias/8JRSL/carteles/index.html index e5a6aaf2e..41f8bae7a 100644 --- a/eventos/Conferencias/8JRSL/carteles/index.html +++ b/eventos/Conferencias/8JRSL/carteles/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Conferencias/8jrsl/index.html b/eventos/Conferencias/8jrsl/index.html index 4be4ec6bc..2b4b35393 100644 --- a/eventos/Conferencias/8jrsl/index.html +++ b/eventos/Conferencias/8jrsl/index.html @@ -29,7 +29,7 @@ Entendiendo Unicode (Facundo Batista) - Aula 3.5, 11hs Introducción a Python (Facundo Batista) - Aula"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/eventos/Conferencias/Eventos/Conferencias/pyconar2013/index.html b/eventos/Conferencias/Eventos/Conferencias/pyconar2013/index.html index ab2a5a1c1..12e70dcb7 100644 --- a/eventos/Conferencias/Eventos/Conferencias/pyconar2013/index.html +++ b/eventos/Conferencias/Eventos/Conferencias/pyconar2013/index.html @@ -30,7 +30,7 @@ http://www.flickr.com/photos/70871182@N04/sets/72157637010046074/"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/eventos/Conferencias/ProcesoSeleccion/propuestadepycon2013encordobacapital/index.html b/eventos/Conferencias/ProcesoSeleccion/propuestadepycon2013encordobacapital/index.html index 60602cc91..f73e0fe45 100644 --- a/eventos/Conferencias/ProcesoSeleccion/propuestadepycon2013encordobacapital/index.html +++ b/eventos/Conferencias/ProcesoSeleccion/propuestadepycon2013encordobacapital/index.html @@ -26,7 +26,7 @@ Duración: 2 a 3 días Lugar: UCC sede centro (preconfirmada); FAMAF-UNC (interesada); Centro de Convenciones en zona centrica (como plan de contingencias) "> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/eventos/Conferencias/ProcesoSeleccion/propuestadepycon2013enrosario/index.html b/eventos/Conferencias/ProcesoSeleccion/propuestadepycon2013enrosario/index.html index c7529221a..0c07fd6c0 100644 --- a/eventos/Conferencias/ProcesoSeleccion/propuestadepycon2013enrosario/index.html +++ b/eventos/Conferencias/ProcesoSeleccion/propuestadepycon2013enrosario/index.html @@ -26,7 +26,7 @@ Estamos en el centro del país y contamos con una amplia red de transportes http://www.rosario.gov.ar/sitio/caracteristicas/geografica2.jsp?nivel=Ciudad&ult=Ci_2 Las autopistas a Buen"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/eventos/Conferencias/PyConAr2016/propuestasedebahia/index.html b/eventos/Conferencias/PyConAr2016/propuestasedebahia/index.html index e07e12edd..84fae09bc 100644 --- a/eventos/Conferencias/PyConAr2016/propuestasedebahia/index.html +++ b/eventos/Conferencias/PyConAr2016/propuestasedebahia/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Conferencias/PyConAr2016/viaje/index.html b/eventos/Conferencias/PyConAr2016/viaje/index.html index 73f22d9fc..78795d11b 100644 --- a/eventos/Conferencias/PyConAr2016/viaje/index.html +++ b/eventos/Conferencias/PyConAr2016/viaje/index.html @@ -30,7 +30,7 @@ Manuel Kaufmann (humitos): No tengo auto. Llego el Miércoles 23 de Noviembre a Bs As a las 18:30hs Johanna Sanchez (ellaquimica"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/eventos/Conferencias/PyConAr2017/propuestasedecordoba/index.html b/eventos/Conferencias/PyConAr2017/propuestasedecordoba/index.html index 3f7193a96..4bac40044 100644 --- a/eventos/Conferencias/PyConAr2017/propuestasedecordoba/index.html +++ b/eventos/Conferencias/PyConAr2017/propuestasedecordoba/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/Conferencias/PyConAr2018/propuestasedecaba/index.html b/eventos/Conferencias/PyConAr2018/propuestasedecaba/index.html index d6bb94af7..26480ca0f 100644 --- a/eventos/Conferencias/PyConAr2018/propuestasedecaba/index.html +++ b/eventos/Conferencias/PyConAr2018/propuestasedecaba/index.html @@ -29,7 +29,7 @@ ¿Por qué en CABA? La primer PyCo"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/eventos/Conferencias/PyConAr2020/propuestaejemplo/index.html b/eventos/Conferencias/PyConAr2020/propuestaejemplo/index.html index 6b2664fb1..ad5be0dd7 100644 --- a/eventos/Conferencias/PyConAr2020/propuestaejemplo/index.html +++ b/eventos/Conferencias/PyConAr2020/propuestaejemplo/index.html @@ -27,7 +27,7 @@ ¿Por qué en Algún Lado Re Copado? Explicar por qué estaría bueno que el evento "> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/eventos/Conferencias/cafeconf2006/index.html b/eventos/Conferencias/cafeconf2006/index.html index 8ef6f3acd..980e9f7b7 100644 --- a/eventos/Conferencias/cafeconf2006/index.html +++ b/eventos/Conferencias/cafeconf2006/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Conferencias/procesoseleccion/index.html b/eventos/Conferencias/procesoseleccion/index.html index 7eb2afbdb..daf08e36c 100644 --- a/eventos/Conferencias/procesoseleccion/index.html +++ b/eventos/Conferencias/procesoseleccion/index.html @@ -34,7 +34,7 @@ Pycon 2013 en Cordoba Capital Pycon 2013 en Rosario"> - + Ir al contenido principal @@ -68,12 +68,12 @@ - + diff --git a/eventos/Conferencias/pycon2006/index.html b/eventos/Conferencias/pycon2006/index.html index 53b7c4faa..c19827c77 100644 --- a/eventos/Conferencias/pycon2006/index.html +++ b/eventos/Conferencias/pycon2006/index.html @@ -28,7 +28,7 @@ Empresas que están usando Pyt"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/eventos/Conferencias/pyconar2013/index.html b/eventos/Conferencias/pyconar2013/index.html index 92afe48e8..77bbb0b7f 100644 --- a/eventos/Conferencias/pyconar2013/index.html +++ b/eventos/Conferencias/pyconar2013/index.html @@ -28,7 +28,7 @@ La conferencia se hizo! Tuvimos muy buenas k"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/eventos/Conferencias/pyconar2014/index.html b/eventos/Conferencias/pyconar2014/index.html index 6ab14062a..852679049 100644 --- a/eventos/Conferencias/pyconar2014/index.html +++ b/eventos/Conferencias/pyconar2014/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Conferencias/pyconar2016/index.html b/eventos/Conferencias/pyconar2016/index.html index 23e73d414..05ea0ab69 100644 --- a/eventos/Conferencias/pyconar2016/index.html +++ b/eventos/Conferencias/pyconar2016/index.html @@ -26,7 +26,7 @@ Sitio oficial http://ar.pycon.org/ Viaje"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/eventos/Conferencias/pyconar2017/index.html b/eventos/Conferencias/pyconar2017/index.html index 3ff20365f..ef739426b 100644 --- a/eventos/Conferencias/pyconar2017/index.html +++ b/eventos/Conferencias/pyconar2017/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Conferencias/pyconar2018/index.html b/eventos/Conferencias/pyconar2018/index.html index dfceaac3e..edb4af824 100644 --- a/eventos/Conferencias/pyconar2018/index.html +++ b/eventos/Conferencias/pyconar2018/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Conferencias/pyconar2020/index.html b/eventos/Conferencias/pyconar2020/index.html index 470ecbae3..633eb4e08 100644 --- a/eventos/Conferencias/pyconar2020/index.html +++ b/eventos/Conferencias/pyconar2020/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/Conferencias/pyconargentina2009/index.html b/eventos/Conferencias/pyconargentina2009/index.html index aa77c0db3..50deca6e8 100644 --- a/eventos/Conferencias/pyconargentina2009/index.html +++ b/eventos/Conferencias/pyconargentina2009/index.html @@ -41,7 +41,7 @@ http"> - + Ir al contenido principal @@ -75,12 +75,12 @@ - + diff --git a/eventos/Conferencias/pyconargentina2010/index.html b/eventos/Conferencias/pyconargentina2010/index.html index 01e1672b3..19e92b112 100644 --- a/eventos/Conferencias/pyconargentina2010/index.html +++ b/eventos/Conferencias/pyconargentina2010/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Conferencias/pydaybuenosaires2010/index.html b/eventos/Conferencias/pydaybuenosaires2010/index.html index 20f8cb7a3..b3672b0e0 100644 --- a/eventos/Conferencias/pydaybuenosaires2010/index.html +++ b/eventos/Conferencias/pydaybuenosaires2010/index.html @@ -28,7 +28,7 @@ Lugar: Asociación Civil Club de Programadores - Auditorios Congreso 3 tracks: Básico, Talleres, Abierto (cosas de la comunidad: postgres, ubu"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/eventos/Conferencias/pydayrafaela2010/index.html b/eventos/Conferencias/pydayrafaela2010/index.html index 441aafdde..3466c3e14 100644 --- a/eventos/Conferencias/pydayrafaela2010/index.html +++ b/eventos/Conferencias/pydayrafaela2010/index.html @@ -38,7 +38,7 @@ Juan Fisanotti Ariel Ro"> - + Ir al contenido principal @@ -72,12 +72,12 @@ - + diff --git a/eventos/Conferencias/pydayrafaela2012/index.html b/eventos/Conferencias/pydayrafaela2012/index.html index c5a03a2e7..6bc7275d9 100644 --- a/eventos/Conferencias/pydayrafaela2012/index.html +++ b/eventos/Conferencias/pydayrafaela2012/index.html @@ -39,7 +39,7 @@ Coordinador cat"> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/eventos/PyCamp/2012/index.html b/eventos/PyCamp/2012/index.html index 5e15432ab..5e7f11d3c 100644 --- a/eventos/PyCamp/2012/index.html +++ b/eventos/PyCamp/2012/index.html @@ -27,7 +27,7 @@ Fecha: Sabado 28/4 arrancando a la matina hasta el Martes 1/5 hasta las 17 pm aprox Hay Internet: Si, por wi"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/eventos/PyDay/2011/Cordoba/comunidadanarquiasubversion/index.html b/eventos/PyDay/2011/Cordoba/comunidadanarquiasubversion/index.html index 8b2c56fde..d2a06ba9d 100644 --- a/eventos/PyDay/2011/Cordoba/comunidadanarquiasubversion/index.html +++ b/eventos/PyDay/2011/Cordoba/comunidadanarquiasubversion/index.html @@ -32,7 +32,7 @@ Pensamientos sobre nuestras comunidades, formas de organización en las distintas etapas de las mismas, y temas relacionados. http://pyar.usla.org.ar/"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/eventos/PyDay/2011/Cordoba/pythonpilas/index.html b/eventos/PyDay/2011/Cordoba/pythonpilas/index.html index c18de0897..35ce6d413 100644 --- a/eventos/PyDay/2011/Cordoba/pythonpilas/index.html +++ b/eventos/PyDay/2011/Cordoba/pythonpilas/index.html @@ -32,7 +32,7 @@ Pilas es un motor o biblioteca para hacer juegos de manera sencilla, orientado a principiantes y programadores. http://pyar.usla.org.ar/pilas001.ogv"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/eventos/PyDay/2011/Cordoba/pythonsugaricaro/index.html b/eventos/PyDay/2011/Cordoba/pythonsugaricaro/index.html index 374dd9783..d412457a2 100644 --- a/eventos/PyDay/2011/Cordoba/pythonsugaricaro/index.html +++ b/eventos/PyDay/2011/Cordoba/pythonsugaricaro/index.html @@ -31,7 +31,7 @@ Presentación de ICARO, un entorno de robotica educativa con software libre diseñado para la escuela inicial y media. implementacion de un modulo pytho"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/eventos/PyDay/2011/Cordoba/pythontests/index.html b/eventos/PyDay/2011/Cordoba/pythontests/index.html index 9226fe293..bf9d43771 100644 --- a/eventos/PyDay/2011/Cordoba/pythontests/index.html +++ b/eventos/PyDay/2011/Cordoba/pythontests/index.html @@ -31,7 +31,7 @@ Todos conocemos y aceptamos la vital importancia de escribir tests para nuestras aplicaciones. Pero no todos efectivamente escribimos esas test suites"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/eventos/PyDay/2011/cordoba/index.html b/eventos/PyDay/2011/cordoba/index.html index 2cbec12ea..f2af960e2 100644 --- a/eventos/PyDay/2011/cordoba/index.html +++ b/eventos/PyDay/2011/cordoba/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2004/reunion01/index.html b/eventos/Reuniones/2004/reunion01/index.html index 6740b417a..868daf037 100644 --- a/eventos/Reuniones/2004/reunion01/index.html +++ b/eventos/Reuniones/2004/reunion01/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/Reuniones/2004/reunion02/index.html b/eventos/Reuniones/2004/reunion02/index.html index f517d26a2..d25d188ab 100644 --- a/eventos/Reuniones/2004/reunion02/index.html +++ b/eventos/Reuniones/2004/reunion02/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2004/reunion03/index.html b/eventos/Reuniones/2004/reunion03/index.html index 8943bda1a..6227b2655 100644 --- a/eventos/Reuniones/2004/reunion03/index.html +++ b/eventos/Reuniones/2004/reunion03/index.html @@ -33,7 +33,7 @@ "> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/eventos/Reuniones/2004/reunion04/index.html b/eventos/Reuniones/2004/reunion04/index.html index 46fa387cc..0e5eb459b 100644 --- a/eventos/Reuniones/2004/reunion04/index.html +++ b/eventos/Reuniones/2004/reunion04/index.html @@ -27,7 +27,7 @@ Sitio Estuvimos de acuerdo en que la complejidad de Zope/Plone, al menos para la estructura actual del grupo, nos está trayendo algunas desventajas. No obstante, decid"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/eventos/Reuniones/2005/reunion05/index.html b/eventos/Reuniones/2005/reunion05/index.html index e3e76d97d..fa31ded9d 100644 --- a/eventos/Reuniones/2005/reunion05/index.html +++ b/eventos/Reuniones/2005/reunion05/index.html @@ -26,7 +26,7 @@ Charlamos con lo"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + @@ -91,13 +91,13 @@

    Reunión 05 - 13/01/2005 - Hip Bar

  • Definimos una cuestión administrativa que teníamos pendiente: ¿qué vamos a hacer con nuestra lista de correo? La decisión final es encontrar una lista que cumpla con nuestras expectativas (que pueda tener nuestro dominio y que tenga archivo) y migrar a ella. Pero antes, nada. Al respecto, yo me llevé como pendiente averiguar que características tienen las listas que puedo hostear en mi sitio.

  • Expuse Decimal. Estuvo muy interesante, porque nos poníamos a discutir sobre la curvatura del círculo, que los complejos tienen infinitos todo alrededor, sobre el pelo del gato y la quinta pata del huevo. ¡Y hasta les pude contar como usar el módulo! Realmente me encantó. Ah, de paso:

  • -
    >>> from decimal import *
    ->>> Decimal("-0")
    -Decimal("-0")
    ->>> Decimal("0")
    -Decimal("0")
    ->>> Decimal("0") == Decimal("-0")
    -True
    +
    >>> from decimal import *
    +>>> Decimal("-0")
    +Decimal("-0")
    +>>> Decimal("0")
    +Decimal("0")
    +>>> Decimal("0") == Decimal("-0")
    +True
     
    • Definimos el tema del Primer Sprint PyAr: vamos a hacer el Administrador de Colas de Mensajes (nombre no oficial), con interfaces SMTP (mail), SMPP (SMSs o mensajes cortos) y MM7 (MMSs o mensajes multimedia). La primer reunión será el Jueves 27 de Enero en el mismo lugar que hicimos la reunión, ya que comenzaremos con el diseño del sistema, y no necesitamos más que papel, lápiz, y buenas ideas (y, por supuesto, cerveeeeza).

    • diff --git a/eventos/Reuniones/2005/reunion06/index.html b/eventos/Reuniones/2005/reunion06/index.html index 2854e4318..b56a46634 100644 --- a/eventos/Reuniones/2005/reunion06/index.html +++ b/eventos/Reuniones/2005/reunion06/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +
    diff --git a/eventos/Reuniones/2005/reunion07/index.html b/eventos/Reuniones/2005/reunion07/index.html index adf8b2c67..09e2c2d13 100644 --- a/eventos/Reuniones/2005/reunion07/index.html +++ b/eventos/Reuniones/2005/reunion07/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/Reuniones/2005/reunion08/index.html b/eventos/Reuniones/2005/reunion08/index.html index e1a6bb5ac..590ac80fa 100644 --- a/eventos/Reuniones/2005/reunion08/index.html +++ b/eventos/Reuniones/2005/reunion08/index.html @@ -26,7 +26,7 @@ Sebastián: Viene de CafeLUG, trabaja en wxPython y Z"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/eventos/Reuniones/2005/reunion09/index.html b/eventos/Reuniones/2005/reunion09/index.html index 6ac215ec3..e276b29a4 100644 --- a/eventos/Reuniones/2005/reunion09/index.html +++ b/eventos/Reuniones/2005/reunion09/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/Reuniones/2005/reunion10/index.html b/eventos/Reuniones/2005/reunion10/index.html index 6fa7da42a..96ef40f6b 100644 --- a/eventos/Reuniones/2005/reunion10/index.html +++ b/eventos/Reuniones/2005/reunion10/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/Reuniones/2005/reunion11/index.html b/eventos/Reuniones/2005/reunion11/index.html index 381e7b564..487d058d2 100644 --- a/eventos/Reuniones/2005/reunion11/index.html +++ b/eventos/Reuniones/2005/reunion11/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2005/reunion12/index.html b/eventos/Reuniones/2005/reunion12/index.html index 9790c9c71..3affb0cee 100644 --- a/eventos/Reuniones/2005/reunion12/index.html +++ b/eventos/Reuniones/2005/reunion12/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2006/reunion13/index.html b/eventos/Reuniones/2006/reunion13/index.html index 4394047e5..61f53308a 100644 --- a/eventos/Reuniones/2006/reunion13/index.html +++ b/eventos/Reuniones/2006/reunion13/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2006/reunion14/index.html b/eventos/Reuniones/2006/reunion14/index.html index e81298121..4cc5324d0 100644 --- a/eventos/Reuniones/2006/reunion14/index.html +++ b/eventos/Reuniones/2006/reunion14/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2006/reunion15/index.html b/eventos/Reuniones/2006/reunion15/index.html index 8d7d06b31..6ffa686ad 100644 --- a/eventos/Reuniones/2006/reunion15/index.html +++ b/eventos/Reuniones/2006/reunion15/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2006/reunion16/index.html b/eventos/Reuniones/2006/reunion16/index.html index 34ddd7f89..554c19ea8 100644 --- a/eventos/Reuniones/2006/reunion16/index.html +++ b/eventos/Reuniones/2006/reunion16/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2006/reunion17/index.html b/eventos/Reuniones/2006/reunion17/index.html index afbb322be..f6b744450 100644 --- a/eventos/Reuniones/2006/reunion17/index.html +++ b/eventos/Reuniones/2006/reunion17/index.html @@ -27,7 +27,7 @@ Adrian"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/eventos/Reuniones/2006/reunion18/index.html b/eventos/Reuniones/2006/reunion18/index.html index 718ab3fb3..f80ac315e 100644 --- a/eventos/Reuniones/2006/reunion18/index.html +++ b/eventos/Reuniones/2006/reunion18/index.html @@ -38,7 +38,7 @@ PabloZiliani Sebastiá"> - + Ir al contenido principal @@ -72,12 +72,12 @@ - + diff --git a/eventos/Reuniones/2006/reunion19/index.html b/eventos/Reuniones/2006/reunion19/index.html index e6cdca754..af2f5f710 100644 --- a/eventos/Reuniones/2006/reunion19/index.html +++ b/eventos/Reuniones/2006/reunion19/index.html @@ -26,7 +26,7 @@ La Casa del Queso, Av. Corrientes 3587, entre Billinghurst y Sánchez de Bustamante, Cap. Fed. Estaríamos, en la parte del primer piso. ¿Cuando? A la salida de CafeConf, o sea, de 19:30hs (gmt-"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/eventos/Reuniones/2006/reunion20/index.html b/eventos/Reuniones/2006/reunion20/index.html index 1c2d8b7a9..e2ebb8c47 100644 --- a/eventos/Reuniones/2006/reunion20/index.html +++ b/eventos/Reuniones/2006/reunion20/index.html @@ -29,7 +29,7 @@ Presentación de los integrantes Presentacíon de cada integrante y actividad actual, a modo de conocernos"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/eventos/Reuniones/2006/reunion21/index.html b/eventos/Reuniones/2006/reunion21/index.html index 6668fc1f2..b6c225116 100644 --- a/eventos/Reuniones/2006/reunion21/index.html +++ b/eventos/Reuniones/2006/reunion21/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2007/reunion22/index.html b/eventos/Reuniones/2007/reunion22/index.html index fdb02c4e0..daa9e442b 100644 --- a/eventos/Reuniones/2007/reunion22/index.html +++ b/eventos/Reuniones/2007/reunion22/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2007/reunion23/index.html b/eventos/Reuniones/2007/reunion23/index.html index 62807cef2..f3bfbd7f9 100644 --- a/eventos/Reuniones/2007/reunion23/index.html +++ b/eventos/Reuniones/2007/reunion23/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2007/reunion24/index.html b/eventos/Reuniones/2007/reunion24/index.html index c0c02f8ae..2b346b98d 100644 --- a/eventos/Reuniones/2007/reunion24/index.html +++ b/eventos/Reuniones/2007/reunion24/index.html @@ -39,7 +39,7 @@ Carlos Gastón Alvarez PabloZil"> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/eventos/Reuniones/2008/reunion25/index.html b/eventos/Reuniones/2008/reunion25/index.html index 35c87ce00..c05af26da 100644 --- a/eventos/Reuniones/2008/reunion25/index.html +++ b/eventos/Reuniones/2008/reunion25/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2008/reunion26/index.html b/eventos/Reuniones/2008/reunion26/index.html index 74493d199..b76a3e455 100644 --- a/eventos/Reuniones/2008/reunion26/index.html +++ b/eventos/Reuniones/2008/reunion26/index.html @@ -39,7 +39,7 @@ Leo De Luca (N) Lucas Deves"> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/eventos/Reuniones/2008/reunion27/index.html b/eventos/Reuniones/2008/reunion27/index.html index be2617eaf..05ac803c8 100644 --- a/eventos/Reuniones/2008/reunion27/index.html +++ b/eventos/Reuniones/2008/reunion27/index.html @@ -51,7 +51,7 @@ Mario"> - + Ir al contenido principal @@ -85,12 +85,12 @@ - + diff --git a/eventos/Reuniones/2008/reunion28/index.html b/eventos/Reuniones/2008/reunion28/index.html index 971803357..dfcf85d43 100644 --- a/eventos/Reuniones/2008/reunion28/index.html +++ b/eventos/Reuniones/2008/reunion28/index.html @@ -41,7 +41,7 @@ SebastianAlvarez"> - + Ir al contenido principal @@ -75,12 +75,12 @@ - + diff --git a/eventos/Reuniones/2008/reunion29/index.html b/eventos/Reuniones/2008/reunion29/index.html index 40e3efdf4..75700cc47 100644 --- a/eventos/Reuniones/2008/reunion29/index.html +++ b/eventos/Reuniones/2008/reunion29/index.html @@ -39,7 +39,7 @@ "> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/eventos/Reuniones/2008/reunion30/index.html b/eventos/Reuniones/2008/reunion30/index.html index 1e12e5bd8..76c542241 100644 --- a/eventos/Reuniones/2008/reunion30/index.html +++ b/eventos/Reuniones/2008/reunion30/index.html @@ -51,7 +51,7 @@ Juan Pablo Giménez"> - + Ir al contenido principal @@ -85,12 +85,12 @@ - + diff --git a/eventos/Reuniones/2008/reunion31/index.html b/eventos/Reuniones/2008/reunion31/index.html index 1f787918c..8ebd5c274 100644 --- a/eventos/Reuniones/2008/reunion31/index.html +++ b/eventos/Reuniones/2008/reunion31/index.html @@ -51,7 +51,7 @@ Manuel "> - + Ir al contenido principal @@ -85,12 +85,12 @@ - + diff --git a/eventos/Reuniones/2008/reunion32/index.html b/eventos/Reuniones/2008/reunion32/index.html index c1d070d96..7b35a5f67 100644 --- a/eventos/Reuniones/2008/reunion32/index.html +++ b/eventos/Reuniones/2008/reunion32/index.html @@ -55,7 +55,7 @@ Trasla"> - + Ir al contenido principal @@ -89,12 +89,12 @@ - + diff --git a/eventos/Reuniones/2008/reunion33/index.html b/eventos/Reuniones/2008/reunion33/index.html index 270119e75..3d3df8200 100644 --- a/eventos/Reuniones/2008/reunion33/index.html +++ b/eventos/Reuniones/2008/reunion33/index.html @@ -32,7 +32,7 @@ "> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/eventos/Reuniones/2008/reunion34/index.html b/eventos/Reuniones/2008/reunion34/index.html index c7c543847..90e8c2235 100644 --- a/eventos/Reuniones/2008/reunion34/index.html +++ b/eventos/Reuniones/2008/reunion34/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/Reuniones/2009/reunion35/index.html b/eventos/Reuniones/2009/reunion35/index.html index e427be1d2..239e407aa 100644 --- a/eventos/Reuniones/2009/reunion35/index.html +++ b/eventos/Reuniones/2009/reunion35/index.html @@ -45,7 +45,7 @@ JohnLento"> - + Ir al contenido principal @@ -79,12 +79,12 @@ - + diff --git a/eventos/Reuniones/2009/reunion36/index.html b/eventos/Reuniones/2009/reunion36/index.html index 424ed8c9c..791ccc101 100644 --- a/eventos/Reuniones/2009/reunion36/index.html +++ b/eventos/Reuniones/2009/reunion36/index.html @@ -40,7 +40,7 @@ ¿De qué se habló? Les pido mil disculpas, pero estoy escribiendo esto 3 meses despues de la reunion 😕 asi q"> - + Ir al contenido principal @@ -74,12 +74,12 @@ - + diff --git a/eventos/Reuniones/2009/reunion37/index.html b/eventos/Reuniones/2009/reunion37/index.html index 71e94370b..3a563f369 100644 --- a/eventos/Reuniones/2009/reunion37/index.html +++ b/eventos/Reuniones/2009/reunion37/index.html @@ -37,7 +37,7 @@ Daniel Leonardo Gabr"> - + Ir al contenido principal @@ -71,12 +71,12 @@ - + diff --git a/eventos/Reuniones/2009/reunion38/index.html b/eventos/Reuniones/2009/reunion38/index.html index cc1cf3f86..3dd7ea8ad 100644 --- a/eventos/Reuniones/2009/reunion38/index.html +++ b/eventos/Reuniones/2009/reunion38/index.html @@ -40,7 +40,7 @@ Gustavo T"> - + Ir al contenido principal @@ -74,12 +74,12 @@ - + diff --git a/eventos/Reuniones/2009/reunion39/index.html b/eventos/Reuniones/2009/reunion39/index.html index 967275137..3b0a758b1 100644 --- a/eventos/Reuniones/2009/reunion39/index.html +++ b/eventos/Reuniones/2009/reunion39/index.html @@ -29,7 +29,7 @@ Como hacer un thread de +150 mails hablando de Python (¿'is == is', o '== is =='?) Como incentivar el crecimiento del ecosistema de Python"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/eventos/Reuniones/2010/reunion40/index.html b/eventos/Reuniones/2010/reunion40/index.html index 942cca35d..2313fd34e 100644 --- a/eventos/Reuniones/2010/reunion40/index.html +++ b/eventos/Reuniones/2010/reunion40/index.html @@ -33,7 +33,7 @@ Los organizadores contaron sobre el lugar elegido, en que días se va a realizar, e hicie"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/eventos/Reuniones/2010/reunion41/index.html b/eventos/Reuniones/2010/reunion41/index.html index b6de67121..98f7f5faa 100644 --- a/eventos/Reuniones/2010/reunion41/index.html +++ b/eventos/Reuniones/2010/reunion41/index.html @@ -39,7 +39,7 @@ JuanFisanotti Ce"> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/eventos/Reuniones/2010/reunion42/index.html b/eventos/Reuniones/2010/reunion42/index.html index 7b71df497..b73195959 100644 --- a/eventos/Reuniones/2010/reunion42/index.html +++ b/eventos/Reuniones/2010/reunion42/index.html @@ -26,7 +26,7 @@ —¡Cuarenta y dos! —exclamó Loonquawl—. ¿Es eso todo lo que tienes que mostrar tras siete millones y medio de años de trabajo? —Lo he comprobado muy minuciosamente —dijo el ordenad"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/eventos/Reuniones/2010/reunion43/index.html b/eventos/Reuniones/2010/reunion43/index.html index e36253c6d..6ff183030 100644 --- a/eventos/Reuniones/2010/reunion43/index.html +++ b/eventos/Reuniones/2010/reunion43/index.html @@ -42,7 +42,7 @@ Daniel Moi"> - + Ir al contenido principal @@ -76,12 +76,12 @@ - + diff --git a/eventos/Reuniones/2010/reunion44/index.html b/eventos/Reuniones/2010/reunion44/index.html index 8b3f5ccca..ad67ec3d9 100644 --- a/eventos/Reuniones/2010/reunion44/index.html +++ b/eventos/Reuniones/2010/reunion44/index.html @@ -38,7 +38,7 @@ Michel Pete"> - + Ir al contenido principal @@ -72,12 +72,12 @@ - + diff --git a/eventos/Reuniones/2010/reunion45/index.html b/eventos/Reuniones/2010/reunion45/index.html index 9eb8dbb82..ce82da5f6 100644 --- a/eventos/Reuniones/2010/reunion45/index.html +++ b/eventos/Reuniones/2010/reunion45/index.html @@ -30,7 +30,7 @@ PyAr y PyBar Llamado por Colaboradores: Proyectos presentados en Conurbania"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/eventos/Reuniones/2010/reunion46/index.html b/eventos/Reuniones/2010/reunion46/index.html index 2ab2b15f8..ff5ca8173 100644 --- a/eventos/Reuniones/2010/reunion46/index.html +++ b/eventos/Reuniones/2010/reunion46/index.html @@ -50,7 +50,7 @@ Minuta El pasado jueves 23 de dici"> - + Ir al contenido principal @@ -84,12 +84,12 @@ - + diff --git a/eventos/Reuniones/2011/reunion47/index.html b/eventos/Reuniones/2011/reunion47/index.html index 2cae4f03a..03cb4483b 100644 --- a/eventos/Reuniones/2011/reunion47/index.html +++ b/eventos/Reuniones/2011/reunion47/index.html @@ -51,7 +51,7 @@ Junt"> - + Ir al contenido principal @@ -85,12 +85,12 @@ - + diff --git a/eventos/Reuniones/2011/reunion48/index.html b/eventos/Reuniones/2011/reunion48/index.html index 8cf7c5b6d..6470c8ca9 100644 --- a/eventos/Reuniones/2011/reunion48/index.html +++ b/eventos/Reuniones/2011/reunion48/index.html @@ -39,7 +39,7 @@ M"> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/eventos/Reuniones/2011/reunion49/index.html b/eventos/Reuniones/2011/reunion49/index.html index eef8619f9..72000ec5b 100644 --- a/eventos/Reuniones/2011/reunion49/index.html +++ b/eventos/Reuniones/2011/reunion49/index.html @@ -39,7 +39,7 @@ Organización de un pyDay en S"> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/eventos/Reuniones/2011/reunion50/index.html b/eventos/Reuniones/2011/reunion50/index.html index d097a40ef..e54d33693 100644 --- a/eventos/Reuniones/2011/reunion50/index.html +++ b/eventos/Reuniones/2011/reunion50/index.html @@ -32,7 +32,7 @@ Promover Python en el sistema educativo Debate: ¿Nos c"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/eventos/Reuniones/2012/reunion51/index.html b/eventos/Reuniones/2012/reunion51/index.html index b2f78c9e3..67a467297 100644 --- a/eventos/Reuniones/2012/reunion51/index.html +++ b/eventos/Reuniones/2012/reunion51/index.html @@ -29,7 +29,7 @@ PyCon Como darle un marco legal y de soporte administrativo a python argentina "> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/eventos/Reuniones/2012/reunion52/index.html b/eventos/Reuniones/2012/reunion52/index.html index af37cb073..60d623766 100644 --- a/eventos/Reuniones/2012/reunion52/index.html +++ b/eventos/Reuniones/2012/reunion52/index.html @@ -30,7 +30,7 @@ PyCon: estado Como darle un marco legal y de soporte administrativo a Python Argentina sin desvirtuar la actual'> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/eventos/Reuniones/2012/reunion53/index.html b/eventos/Reuniones/2012/reunion53/index.html index b0d4f667f..a2ff322a2 100644 --- a/eventos/Reuniones/2012/reunion53/index.html +++ b/eventos/Reuniones/2012/reunion53/index.html @@ -51,7 +51,7 @@ DavidLitvak|David Lit"> - + Ir al contenido principal @@ -85,12 +85,12 @@ - + diff --git a/eventos/Reuniones/2012/reunion54/index.html b/eventos/Reuniones/2012/reunion54/index.html index e04338216..8f85c2555 100644 --- a/eventos/Reuniones/2012/reunion54/index.html +++ b/eventos/Reuniones/2012/reunion54/index.html @@ -31,7 +31,7 @@ Pines de Android, New Relic y otras Frisbees, helicoptercitos, "> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/eventos/Reuniones/2012/reunion55/index.html b/eventos/Reuniones/2012/reunion55/index.html index 8831982d2..3747a1516 100644 --- a/eventos/Reuniones/2012/reunion55/index.html +++ b/eventos/Reuniones/2012/reunion55/index.html @@ -67,7 +67,7 @@ Fech"> - + Ir al contenido principal @@ -101,12 +101,12 @@ - + diff --git a/eventos/Reuniones/2012/reunion56/index.html b/eventos/Reuniones/2012/reunion56/index.html index 9b0eba09d..64536ad04 100644 --- a/eventos/Reuniones/2012/reunion56/index.html +++ b/eventos/Reuniones/2012/reunion56/index.html @@ -30,7 +30,7 @@ Actividades Sociales: ¡Fiesta!, Asado/Picnic y día turístico Revisar el Ll"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/eventos/Reuniones/2012/reunion57/index.html b/eventos/Reuniones/2012/reunion57/index.html index f173fee0c..ba2ff0a6d 100644 --- a/eventos/Reuniones/2012/reunion57/index.html +++ b/eventos/Reuniones/2012/reunion57/index.html @@ -36,7 +36,7 @@ Cristian Cravero Biassotti Danie"> - + Ir al contenido principal @@ -70,12 +70,12 @@ - + diff --git a/eventos/Reuniones/2012/reunion58/index.html b/eventos/Reuniones/2012/reunion58/index.html index b4da24b11..0eb7a9ed9 100644 --- a/eventos/Reuniones/2012/reunion58/index.html +++ b/eventos/Reuniones/2012/reunion58/index.html @@ -65,7 +65,7 @@ Miérco"> - + Ir al contenido principal @@ -99,12 +99,12 @@ - + diff --git a/eventos/Reuniones/2013/reunion59/index.html b/eventos/Reuniones/2013/reunion59/index.html index dadec107d..0001f7a3b 100644 --- a/eventos/Reuniones/2013/reunion59/index.html +++ b/eventos/Reuniones/2013/reunion59/index.html @@ -41,7 +41,7 @@ Persona Primera"> - + Ir al contenido principal @@ -75,12 +75,12 @@ - + diff --git a/eventos/Reuniones/2013/reunion60/index.html b/eventos/Reuniones/2013/reunion60/index.html index 5890b9037..431ed36f1 100644 --- a/eventos/Reuniones/2013/reunion60/index.html +++ b/eventos/Reuniones/2013/reunion60/index.html @@ -47,7 +47,7 @@ José Ro"> - + Ir al contenido principal @@ -81,12 +81,12 @@ - + diff --git a/eventos/Reuniones/2013/reunion61/index.html b/eventos/Reuniones/2013/reunion61/index.html index 61506db3d..b9e462f16 100644 --- a/eventos/Reuniones/2013/reunion61/index.html +++ b/eventos/Reuniones/2013/reunion61/index.html @@ -50,7 +50,7 @@ Elvio Rogelio Tocca"> - + Ir al contenido principal @@ -84,12 +84,12 @@ - + diff --git a/eventos/Reuniones/2014/reunion62/index.html b/eventos/Reuniones/2014/reunion62/index.html index 1860238b4..680701b50 100644 --- a/eventos/Reuniones/2014/reunion62/index.html +++ b/eventos/Reuniones/2014/reunion62/index.html @@ -28,7 +28,7 @@ Juan Gabardini va a venir y nos va a contar la experiencia de pertenecer a SADIO (lo cual nos daría personería) ¿Está bien que PyAr ponga plata para proyectos de PyAr? "> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/eventos/Reuniones/2014/reunion63/index.html b/eventos/Reuniones/2014/reunion63/index.html index d527c8ed3..67445d7be 100644 --- a/eventos/Reuniones/2014/reunion63/index.html +++ b/eventos/Reuniones/2014/reunion63/index.html @@ -43,7 +43,7 @@ Eloy "> - + Ir al contenido principal @@ -77,12 +77,12 @@ - + diff --git a/eventos/Reuniones/2014/reunion64/index.html b/eventos/Reuniones/2014/reunion64/index.html index 042213bbe..c793fb40e 100644 --- a/eventos/Reuniones/2014/reunion64/index.html +++ b/eventos/Reuniones/2014/reunion64/index.html @@ -26,7 +26,7 @@ Rafaela Python Porque pintó"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/eventos/Reuniones/2015/reunion65/index.html b/eventos/Reuniones/2015/reunion65/index.html index 66be4e8ec..0e47d15e9 100644 --- a/eventos/Reuniones/2015/reunion65/index.html +++ b/eventos/Reuniones/2015/reunion65/index.html @@ -37,7 +37,7 @@ Minuta Se charlon varios temas los pri"> - + Ir al contenido principal @@ -71,12 +71,12 @@ - + diff --git a/eventos/Reuniones/2016/reunion66/index.html b/eventos/Reuniones/2016/reunion66/index.html index 8f207d9b7..7ed22c455 100644 --- a/eventos/Reuniones/2016/reunion66/index.html +++ b/eventos/Reuniones/2016/reunion66/index.html @@ -37,7 +37,7 @@ Minuta Se charlaron varios temas, los p"> - + Ir al contenido principal @@ -71,12 +71,12 @@ - + diff --git a/eventos/Reuniones/2017/reunion67/index.html b/eventos/Reuniones/2017/reunion67/index.html index 9d861e4b5..cc1cea1ca 100644 --- a/eventos/Reuniones/2017/reunion67/index.html +++ b/eventos/Reuniones/2017/reunion67/index.html @@ -36,7 +36,7 @@ Leandro E. Colombo Viña Nestor G"> - + Ir al contenido principal @@ -70,12 +70,12 @@ - + diff --git a/eventos/Reuniones/2017/reunion68/index.html b/eventos/Reuniones/2017/reunion68/index.html index f4be49548..d98243b78 100644 --- a/eventos/Reuniones/2017/reunion68/index.html +++ b/eventos/Reuniones/2017/reunion68/index.html @@ -32,7 +32,7 @@ Cristina Pedrani Cynthia M"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/eventos/Reuniones/2017/reunion69/index.html b/eventos/Reuniones/2017/reunion69/index.html index c88c5b364..bf4f3ba31 100644 --- a/eventos/Reuniones/2017/reunion69/index.html +++ b/eventos/Reuniones/2017/reunion69/index.html @@ -39,7 +39,7 @@ PyCon 2017: ¡hay propuesta! ¿cuándo es? ¿dónde? ¿cómo viene la"> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/eventos/Reuniones/2018/reunion70/index.html b/eventos/Reuniones/2018/reunion70/index.html index b5349ae60..c65ece223 100644 --- a/eventos/Reuniones/2018/reunion70/index.html +++ b/eventos/Reuniones/2018/reunion70/index.html @@ -33,7 +33,7 @@ Berenice Larsen Pereyra Bruno Geninatti"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/eventos/Reuniones/2019/reunion71/index.html b/eventos/Reuniones/2019/reunion71/index.html index 4019cc2ab..0f6ad5e74 100644 --- a/eventos/Reuniones/2019/reunion71/index.html +++ b/eventos/Reuniones/2019/reunion71/index.html @@ -35,7 +35,7 @@ Cristina Pedrani Cynthia Monastirs"> - + Ir al contenido principal @@ -69,12 +69,12 @@ - + diff --git a/eventos/Reuniones/2019/reunion72/index.html b/eventos/Reuniones/2019/reunion72/index.html index d8637122d..f83b1c837 100644 --- a/eventos/Reuniones/2019/reunion72/index.html +++ b/eventos/Reuniones/2019/reunion72/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/Reuniones/proximareunion/index.html b/eventos/Reuniones/proximareunion/index.html index 1d2694098..01265fa42 100644 --- a/eventos/Reuniones/proximareunion/index.html +++ b/eventos/Reuniones/proximareunion/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/Reuniones/releaseprocedure/index.html b/eventos/Reuniones/releaseprocedure/index.html index 8fcd2d8d7..a2874c05c 100644 --- a/eventos/Reuniones/releaseprocedure/index.html +++ b/eventos/Reuniones/releaseprocedure/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/Sprints/olpcserver/index.html b/eventos/Sprints/olpcserver/index.html index 5d25660e5..a785b2fe3 100644 --- a/eventos/Sprints/olpcserver/index.html +++ b/eventos/Sprints/olpcserver/index.html @@ -29,7 +29,7 @@ veamos que módulos sería mas útil y pode"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/eventos/Sprints/wikipediaoffline1/index.html b/eventos/Sprints/wikipediaoffline1/index.html index bbcfd1e9a..7c432edaa 100644 --- a/eventos/Sprints/wikipediaoffline1/index.html +++ b/eventos/Sprints/wikipediaoffline1/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/conferencias/index.html b/eventos/conferencias/index.html index add19c0e1..b166c7d11 100644 --- a/eventos/conferencias/index.html +++ b/eventos/conferencias/index.html @@ -28,7 +28,7 @@ Pycon Argentina 2016, realizada los días 25, 26 y 27 de Noviembre - Bahía Blanca. PyCon Argentina 2015, rea"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/eventos/djangolaunchparty/index.html b/eventos/djangolaunchparty/index.html index 5a7482f48..8f5687ea2 100644 --- a/eventos/djangolaunchparty/index.html +++ b/eventos/djangolaunchparty/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/index.html b/eventos/index.html index 73063d508..91b228baf 100644 --- a/eventos/index.html +++ b/eventos/index.html @@ -28,7 +28,7 @@ Eventos En PyAr planeamos cuatro tipos de eventos"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/eventos/pythonbugday/index.html b/eventos/pythonbugday/index.html index 051ef58e8..8847fb665 100644 --- a/eventos/pythonbugday/index.html +++ b/eventos/pythonbugday/index.html @@ -31,7 +31,7 @@ Buenos Aires (Nuñez) Livra/De"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/eventos/pythonday3/index.html b/eventos/pythonday3/index.html index 74871a346..644ce4edd 100644 --- a/eventos/pythonday3/index.html +++ b/eventos/pythonday3/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/eventos/reuniones/index.html b/eventos/reuniones/index.html index e6f4140ed..beb819d79 100644 --- a/eventos/reuniones/index.html +++ b/eventos/reuniones/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/eventos/sprints/index.html b/eventos/sprints/index.html index 2fbd21258..a9921c874 100644 --- a/eventos/sprints/index.html +++ b/eventos/sprints/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/extraermails/index.html b/extraermails/index.html index 01ca4854c..b4a7a6ea8 100644 --- a/extraermails/index.html +++ b/extraermails/index.html @@ -29,7 +29,7 @@ El código anterior devuelve una lista de strings, donde cada string es una "> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + @@ -88,9 +88,9 @@

    Extraer Direcciones De Email De Un Texto

    Código

    -
    >>> import re
    ->>> mailsrch = re.compile(r'[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}')
    ->>> mailsrch.findall(texto)
    +
    >>> import re
    +>>> mailsrch = re.compile(r'[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}')
    +>>> mailsrch.findall(texto)
     

    El código anterior devuelve una lista de strings, donde cada string es una dirección de email. El texto original puede contener basura como espcios, comas u otros caracteres.

    Autor

    diff --git a/ezequielmarquez/index.html b/ezequielmarquez/index.html index 3a6ae6b02..2a209f495 100644 --- a/ezequielmarquez/index.html +++ b/ezequielmarquez/index.html @@ -26,7 +26,7 @@ Web Site Twitter"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    diff --git a/facundobatista/index.html b/facundobatista/index.html index b4eeda6e8..1c88c61ba 100644 --- a/facundobatista/index.html +++ b/facundobatista/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/filly/index.html b/filly/index.html index f8cc2aaa3..a70b97cfb 100644 --- a/filly/index.html +++ b/filly/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/fixme/index.html b/fixme/index.html index 284c6e9d7..303e131d3 100644 --- a/fixme/index.html +++ b/fixme/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/folletoscarteles/index.html b/folletoscarteles/index.html index 5a2ae31a5..772f6446a 100644 --- a/folletoscarteles/index.html +++ b/folletoscarteles/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/foo/index.html b/foo/index.html index 301f1a3c8..04b77e791 100644 --- a/foo/index.html +++ b/foo/index.html @@ -30,7 +30,7 @@ Testing 5 twitter"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/foro_y_redes/index.html b/foro_y_redes/index.html index 8f4e06264..fde85773c 100644 --- a/foro_y_redes/index.html +++ b/foro_y_redes/index.html @@ -27,7 +27,7 @@ Está basado en Discourse, así que se puede utilizar como foro puro, pero tambi"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/fullsearchcachedcategorywxpython/index.html b/fullsearchcachedcategorywxpython/index.html index 13d1ed312..c4ef2c17d 100644 --- a/fullsearchcachedcategorywxpython/index.html +++ b/fullsearchcachedcategorywxpython/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/fullsearchcategorycategoryvideo/index.html b/fullsearchcategorycategoryvideo/index.html index 1689982b0..45af6807d 100644 --- a/fullsearchcategorycategoryvideo/index.html +++ b/fullsearchcategorycategoryvideo/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/gabrielbrunacci/index.html b/gabrielbrunacci/index.html index be51a6f57..023ee0a0e 100644 --- a/gabrielbrunacci/index.html +++ b/gabrielbrunacci/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/gabrielgenellina/index.html b/gabrielgenellina/index.html index e46d9c20e..c3dff2a93 100644 --- a/gabrielgenellina/index.html +++ b/gabrielgenellina/index.html @@ -26,7 +26,7 @@ Email: lainicialdeminombreseguidademiapellido arroba gmail punto com ..."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/gastemosla/index.html b/gastemosla/index.html index f824b007e..bcd04e6c8 100644 --- a/gastemosla/index.html +++ b/gastemosla/index.html @@ -28,7 +28,7 @@ Pagar para mejorar algunas cosas institucionales de PyAr (i.e.: mejora del frontArpage de PyAr) Imprimir tutor"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/gatox/index.html b/gatox/index.html index a3ccbb847..44096b34a 100644 --- a/gatox/index.html +++ b/gatox/index.html @@ -28,7 +28,7 @@ NINJA-IDE Página Oficial: http://ninja-ide.org NINJA-IDE Source Co"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/gauchitogil/index.html b/gauchitogil/index.html index 75bf18eb6..dd2b58806 100644 --- a/gauchitogil/index.html +++ b/gauchitogil/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/gnomeart/index.html b/gnomeart/index.html index 3ebc4baaf..51df5a59f 100644 --- a/gnomeart/index.html +++ b/gnomeart/index.html @@ -34,7 +34,7 @@ realizar interfaz con glade-3 A"> - + Ir al contenido principal @@ -68,12 +68,12 @@ - + diff --git a/gonzalodelgado/index.html b/gonzalodelgado/index.html index 3635b8cd4..e026f8cea 100644 --- a/gonzalodelgado/index.html +++ b/gonzalodelgado/index.html @@ -26,7 +26,7 @@ Soy Programador Universitario de la Facultad de Ciencias Exactas y Tecnología de la UNT Trabajé en Fortix desde el año 2006 hasta el año 2009 como sysadmin. Es allí "> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/gonzalolarralde/index.html b/gonzalolarralde/index.html index 72eb59fb6..27fada833 100644 --- a/gonzalolarralde/index.html +++ b/gonzalolarralde/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/gonzalopedone/index.html b/gonzalopedone/index.html index 3e3194c26..c333d9d43 100644 --- a/gonzalopedone/index.html +++ b/gonzalopedone/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/grupo-de-entusiastas-de-python/index.html b/grupo-de-entusiastas-de-python/index.html index 4b3e3e68e..99245f159 100644 --- a/grupo-de-entusiastas-de-python/index.html +++ b/grupo-de-entusiastas-de-python/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/gsoc/index.html b/gsoc/index.html index edba96cd6..e7bdb4916 100644 --- a/gsoc/index.html +++ b/gsoc/index.html @@ -31,7 +31,7 @@ El Googl"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/guardarhistorialenconsolainteractiva/index.html b/guardarhistorialenconsolainteractiva/index.html index 41e534ecf..d0d918500 100644 --- a/guardarhistorialenconsolainteractiva/index.html +++ b/guardarhistorialenconsolainteractiva/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -85,22 +85,22 @@

    Guardar Historial En Consola Interactiva

    como guardar y recuperar el historial de las sesiones en la consola interactiva (donado por Matias Ribecky)

    crear un archivo llamado .pythonrc (se llama asi pero podria llamarse de cualquier otra forma), que dice:

    -
    import os
    -import sys
    -import atexit
    -
    -history_path = os.path.expanduser("~/.pyhistory")
    -
    -def save_history():
    -    import readline
    -    readline.write_history_file(history_path)
    -
    -if os.path.exists(history_path):
    -    readline.read_history_file(history_path)
    -
    -atexit.register(save_history)
    -
    -del os, sys, atexit, readline, rlcompleter, save_history, history_path
    +
    import os
    +import sys
    +import atexit
    +
    +history_path = os.path.expanduser("~/.pyhistory")
    +
    +def save_history():
    +    import readline
    +    readline.write_history_file(history_path)
    +
    +if os.path.exists(history_path):
    +    readline.read_history_file(history_path)
    +
    +atexit.register(save_history)
    +
    +del os, sys, atexit, readline, rlcompleter, save_history, history_path
     

    y en el environment se setteada la variable

    PYTHONSTARTUP=/home/tuusuario/.pythonrc (aca importa que sea igual al nombre del alchivo).

    diff --git a/guillermofreschi/index.html b/guillermofreschi/index.html index 70a503961..0b367c7be 100644 --- a/guillermofreschi/index.html +++ b/guillermofreschi/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +
    diff --git a/guillermogonzalez/index.html b/guillermogonzalez/index.html index c966218a5..edc5bf7bd 100644 --- a/guillermogonzalez/index.html +++ b/guillermogonzalez/index.html @@ -26,7 +26,7 @@ Email: guillo.gonzo AT SPAMFREE gmail DOT com ..."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    diff --git a/h/index.html b/h/index.html index 5303647a1..3e0d2e687 100644 --- a/h/index.html +++ b/h/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/hectorsanchez/index.html b/hectorsanchez/index.html index 20992eb38..4c3d7dc4b 100644 --- a/hectorsanchez/index.html +++ b/hectorsanchez/index.html @@ -32,7 +32,7 @@ Competencia internacional PyWeek Va"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/helponmoinwikisynutax/index.html b/helponmoinwikisynutax/index.html index 98a94e45c..44738fcc2 100644 --- a/helponmoinwikisynutax/index.html +++ b/helponmoinwikisynutax/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/hernanolivera/index.html b/hernanolivera/index.html index b33560a4b..be88d065c 100644 --- a/hernanolivera/index.html +++ b/hernanolivera/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/hgttp/index.html b/hgttp/index.html index 41ef11bec..0eb996c80 100644 --- a/hgttp/index.html +++ b/hgttp/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/hipbar/index.html b/hipbar/index.html index 13aa34a49..1024fe3ea 100644 --- a/hipbar/index.html +++ b/hipbar/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/horaciobertorello/index.html b/horaciobertorello/index.html index 08803c958..6b632df4c 100644 --- a/horaciobertorello/index.html +++ b/horaciobertorello/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/horacioduran/index.html b/horacioduran/index.html index 5d199c20d..6998651c4 100644 --- a/horacioduran/index.html +++ b/horacioduran/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/howtoconferencia/index.html b/howtoconferencia/index.html index 2c3fcd3c0..943001c52 100644 --- a/howtoconferencia/index.html +++ b/howtoconferencia/index.html @@ -27,7 +27,7 @@ How to… or backstage about I Jornada Python Santa Fe PyCon Argentina 2009, ¡termi"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/hugoruscitti/index.html b/hugoruscitti/index.html index 7f061cee9..bdfe3d9ab 100644 --- a/hugoruscitti/index.html +++ b/hugoruscitti/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/ideal/index.html b/ideal/index.html index eeb36fbb8..ce54b57b0 100644 --- a/ideal/index.html +++ b/ideal/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/ideas-para-programar/index.html b/ideas-para-programar/index.html index 46bd5dbd3..f22c6c84f 100644 --- a/ideas-para-programar/index.html +++ b/ideas-para-programar/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/ides/index.html b/ides/index.html index 459d32ca8..9c25b7f52 100644 --- a/ides/index.html +++ b/ides/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/index.html b/index.html index f71ed6fae..a66f19e75 100644 --- a/index.html +++ b/index.html @@ -37,7 +37,7 @@ Foro y Redes Información sobre el foro (nuestro principal canal de com"> - + Ir al contenido principal @@ -71,12 +71,12 @@ - + diff --git a/infraestuctura/index.html b/infraestuctura/index.html index f0e3a5a9d..1c3cbf983 100644 --- a/infraestuctura/index.html +++ b/infraestuctura/index.html @@ -28,7 +28,7 @@ Con"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/interesadosentrabajo/index.html b/interesadosentrabajo/index.html index 660b10f70..8b557d501 100644 --- a/interesadosentrabajo/index.html +++ b/interesadosentrabajo/index.html @@ -39,7 +39,7 @@ FacundoBatis"> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/interfacesgraficas/index.html b/interfacesgraficas/index.html index 1f03ff48a..dfb9770f0 100644 --- a/interfacesgraficas/index.html +++ b/interfacesgraficas/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -274,79 +274,79 @@

    Interfaces Gráficas (Gui)

    Nota: para poder comparar, los ejemplos crean una aplicación, ventana y botón, con un evento.

    Hay mas ejemplos en el recetario

    TkInter

    -
    from Tkinter import *
    -
    -class App:
    -    def __init__(self, master):
    -        frame = Frame(master)
    -        frame.pack()
    -        self.hi_there = Button(frame, text="Hola", command=self.say_hi)
    -        self.hi_there.pack(side=LEFT)
    -    def say_hi(self):
    -        print "hola todo el mundo!"
    -
    -root = Tk()
    -app = App(root)
    -root.mainloop()
    +
    from Tkinter import *
    +
    +class App:
    +    def __init__(self, master):
    +        frame = Frame(master)
    +        frame.pack()
    +        self.hi_there = Button(frame, text="Hola", command=self.say_hi)
    +        self.hi_there.pack(side=LEFT)
    +    def say_hi(self):
    +        print "hola todo el mundo!"
    +
    +root = Tk()
    +app = App(root)
    +root.mainloop()
     

    WxPython

    -
    import wx
    -class MyFrame(wx.Frame):
    -    def __init__(self, parent, title):
    -        wx.Frame.__init__(self, parent, -1, title )
    -        btn = wx.Button(self, -1, "Hola")
    -        self.Bind(wx.EVT_BUTTON, self.say_hello, btn)
    -
    -    def say_hello(self,*arg):
    -        print "hola todo el mundo!"
    -
    -class MyApp(wx.App):
    -    def OnInit(self):
    -        frame = MyFrame(None, "Simple wxPython App")
    -        frame.Show(True)
    -        return True
    -MyApp().MainLoop()
    +
    import wx
    +class MyFrame(wx.Frame):
    +    def __init__(self, parent, title):
    +        wx.Frame.__init__(self, parent, -1, title )
    +        btn = wx.Button(self, -1, "Hola")
    +        self.Bind(wx.EVT_BUTTON, self.say_hello, btn)
    +
    +    def say_hello(self,*arg):
    +        print "hola todo el mundo!"
    +
    +class MyApp(wx.App):
    +    def OnInit(self):
    +        frame = MyFrame(None, "Simple wxPython App")
    +        frame.Show(True)
    +        return True
    +MyApp().MainLoop()
     

    PyQt

    -
    from PyQt4 import QtCore, QtGui
    -import sys
    -
    -class MiVentana(QtGui.QWidget):
    -    def __init__(self, padre = None):
    -        super(MiVentana, self).__init__(padre)
    -        self.button = QtGui.QPushButton("Hola",self)
    -        self.connect(self.button, QtCore.SIGNAL("clicked()"), self.say_hello)
    -        self.show()
    -    def say_hello(self,**kwargs):
    -        print "hola mundo!"
    -
    -app = QtGui.QApplication(sys.argv)
    -v = MiVentana()
    -app.exec_()
    +
    from PyQt4 import QtCore, QtGui
    +import sys
    +
    +class MiVentana(QtGui.QWidget):
    +    def __init__(self, padre = None):
    +        super(MiVentana, self).__init__(padre)
    +        self.button = QtGui.QPushButton("Hola",self)
    +        self.connect(self.button, QtCore.SIGNAL("clicked()"), self.say_hello)
    +        self.show()
    +    def say_hello(self,**kwargs):
    +        print "hola mundo!"
    +
    +app = QtGui.QApplication(sys.argv)
    +v = MiVentana()
    +app.exec_()
     

    PyGTK

    -
    import pygtk
    -pygtk.require('2.0')
    -import gtk
    -
    -class HelloWorld:
    -    def __init__(self):
    -        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    -        self.button = gtk.Button("Hello World")
    -        self.button.connect("clicked", self.say_hello, None)
    -        self.window.add(self.button)
    -        self.button.show()
    -        self.window.show()
    -
    -    def main(self):
    -        gtk.main()
    -
    -    def say_hello(self, widget, data=None):
    -        print "Hello World"
    -
    -
    -hello = HelloWorld()
    -hello.main()
    +
    import pygtk
    +pygtk.require('2.0')
    +import gtk
    +
    +class HelloWorld:
    +    def __init__(self):
    +        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    +        self.button = gtk.Button("Hello World")
    +        self.button.connect("clicked", self.say_hello, None)
    +        self.window.add(self.button)
    +        self.button.show()
    +        self.window.show()
    +
    +    def main(self):
    +        gtk.main()
    +
    +    def say_hello(self, widget, data=None):
    +        print "Hello World"
    +
    +
    +hello = HelloWorld()
    +hello.main()
     

    (sin testear)

    Referencias

    diff --git a/invitacioncuentawave/index.html b/invitacioncuentawave/index.html index e26e798c8..9b4d46f58 100644 --- a/invitacioncuentawave/index.html +++ b/invitacioncuentawave/index.html @@ -26,7 +26,7 @@ Esta lista es para hacer una petición mas "ordenada" de las personas que quieren invitaciones para Google WAVE Escribí tu nombre acá y pronto te harán lle'> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/irc/index.html b/irc/index.html index ec3b44e39..2b16a6257 100644 --- a/irc/index.html +++ b/irc/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/javiercastrillo/index.html b/javiercastrillo/index.html index b0c45b481..c6763217c 100644 --- a/javiercastrillo/index.html +++ b/javiercastrillo/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/joaquinsorianello/index.html b/joaquinsorianello/index.html index db87f3a55..5118e619d 100644 --- a/joaquinsorianello/index.html +++ b/joaquinsorianello/index.html @@ -28,7 +28,7 @@ Soy desarrollador de software autodidacta y me gusta trabajar en areas que van del arte programatico a los sistemas de alta disponibilidad. Naci en Bariloche, actualm"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/joaquintita/index.html b/joaquintita/index.html index c5551e970..bdd1a55a3 100644 --- a/joaquintita/index.html +++ b/joaquintita/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/johnlenton/index.html b/johnlenton/index.html index 0155799d2..d76074112 100644 --- a/johnlenton/index.html +++ b/johnlenton/index.html @@ -26,7 +26,7 @@ |http://except.com.ar/| Soy uno de los fundadores de GrULiC (el grupo de usuarios de software libre de Córdoba) |http://www.vialibre.org."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/joseluisdallapiccola/index.html b/joseluisdallapiccola/index.html index 85f48d092..fc4143fe5 100644 --- a/joseluisdallapiccola/index.html +++ b/joseluisdallapiccola/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/juanfisanotti/index.html b/juanfisanotti/index.html index d746bfef9..6c35abf16 100644 --- a/juanfisanotti/index.html +++ b/juanfisanotti/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/juanjociarlante/index.html b/juanjociarlante/index.html index 7244be94c..c59a46a31 100644 --- a/juanjociarlante/index.html +++ b/juanjociarlante/index.html @@ -26,7 +26,7 @@ Soy apasionado del Software Libre desde '93, cuando booteé por primera vez un Yggdrasil en mi 386 (partidura-de-cabeza si las hay...). Mi primer"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/juanjoconti/index.html b/juanjoconti/index.html index 85931b336..d0cb782e8 100644 --- a/juanjoconti/index.html +++ b/juanjoconti/index.html @@ -27,7 +27,7 @@ Juanjo Conti Soy ingeniero de la FRSF-UTN, trabajo en una empresa de telecomunicaciones y tengo una beca de la UTN para investigar y realizar una maestría. Uso Python hace 4 años. Tengo un bl"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/juegos/index.html b/juegos/index.html index a2a382707..a19b34ef3 100644 --- a/juegos/index.html +++ b/juegos/index.html @@ -32,7 +32,7 @@ PyWeek6 "> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/juegos/typuspocus/index.html b/juegos/typuspocus/index.html index c7b0147ca..bca05fb0e 100644 --- a/juegos/typuspocus/index.html +++ b/juegos/typuspocus/index.html @@ -26,7 +26,7 @@ Release 1.0'> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/juegos/worldst/index.html b/juegos/worldst/index.html index 2f8679af7..774f8d9de 100644 --- a/juegos/worldst/index.html +++ b/juegos/worldst/index.html @@ -29,7 +29,7 @@ history by lucio trivia by"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/kaufmannmanuel/index.html b/kaufmannmanuel/index.html index 19981f579..aa9a8861a 100644 --- a/kaufmannmanuel/index.html +++ b/kaufmannmanuel/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/kola/index.html b/kola/index.html index 179a2da18..33307c418 100644 --- a/kola/index.html +++ b/kola/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/labanderadepyar/index.html b/labanderadepyar/index.html index 0719b3b94..9e65e5785 100644 --- a/labanderadepyar/index.html +++ b/labanderadepyar/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/leandrocolombovina/index.html b/leandrocolombovina/index.html index 53500e1e1..2fe3d0122 100644 --- a/leandrocolombovina/index.html +++ b/leandrocolombovina/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/leitomonk/index.html b/leitomonk/index.html index 03a0b25de..25187dff6 100644 --- a/leitomonk/index.html +++ b/leitomonk/index.html @@ -26,7 +26,7 @@ Home: http://audiolibre.com.ar/ Miembro de gcoop"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/libreriasparajuegos/index.html b/libreriasparajuegos/index.html index 3229dc378..84064538c 100644 --- a/libreriasparajuegos/index.html +++ b/libreriasparajuegos/index.html @@ -46,7 +46,7 @@ Recursos Adicionales"> - + Ir al contenido principal @@ -80,12 +80,12 @@ - + diff --git a/lista-de-charlas-realizadas/index.html b/lista-de-charlas-realizadas/index.html index 7a658a27f..ada2ffbe3 100644 --- a/lista-de-charlas-realizadas/index.html +++ b/lista-de-charlas-realizadas/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/listab/index.html b/listab/index.html index 586b5f598..dc02944dd 100644 --- a/listab/index.html +++ b/listab/index.html @@ -27,7 +27,7 @@ ||'''Batteries Included?''' || [[Rating(BatteriesIncluded)]] || ||'''How Does It Make You Feel?'''"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/listadecorreo/index.html b/listadecorreo/index.html index bdd6fc645..aa0b4ca71 100644 --- a/listadecorreo/index.html +++ b/listadecorreo/index.html @@ -27,7 +27,7 @@ Está basado en Discourse, así que se puede utilizar como foro puro, pero tambi"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/llamadoasedepyconar2012/index.html b/llamadoasedepyconar2012/index.html index b1ec11e79..09bdb5487 100644 --- a/llamadoasedepyconar2012/index.html +++ b/llamadoasedepyconar2012/index.html @@ -26,7 +26,7 @@ Estimados pythoner@s, los invitamos a proponerse ustedes y a su ciudad como la posible sede de la próxima Pycon Argentina. Vamos a recibir propuestas hasta el 15 de No"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/lucianorossi/index.html b/lucianorossi/index.html index c539da64e..cbc96c610 100644 --- a/lucianorossi/index.html +++ b/lucianorossi/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/luciotorre/index.html b/luciotorre/index.html index 421ae4db6..0808fc36a 100644 --- a/luciotorre/index.html +++ b/luciotorre/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/luis-nagel/index.html b/luis-nagel/index.html index 21c43a1be..f833d1ac0 100644 --- a/luis-nagel/index.html +++ b/luis-nagel/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/mailtopyar-at-python-dot-org-dot-ar/index.html b/mailtopyar-at-python-dot-org-dot-ar/index.html index 9236b0a52..217528d3e 100644 --- a/mailtopyar-at-python-dot-org-dot-ar/index.html +++ b/mailtopyar-at-python-dot-org-dot-ar/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/manuelquinones/index.html b/manuelquinones/index.html index 54b371531..1d05d04cb 100644 --- a/manuelquinones/index.html +++ b/manuelquinones/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/maram/index.html b/maram/index.html index 800fd4fac..27d3e03f1 100644 --- a/maram/index.html +++ b/maram/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/marceloalaniz/index.html b/marceloalaniz/index.html index 2bfc65610..f6db89881 100644 --- a/marceloalaniz/index.html +++ b/marceloalaniz/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/marcelofernandez/index.html b/marcelofernandez/index.html index ec37b58f4..00369465f 100644 --- a/marcelofernandez/index.html +++ b/marcelofernandez/index.html @@ -27,7 +27,7 @@ Email: marcelo.fidel.fernandez AT SPAMFREE gmail DOT com Pueden encontrar experimentos, comentarios, investigación, en mi blog"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/marcosdione/index.html b/marcosdione/index.html index 7e20ad9a9..4a82e3a88 100644 --- a/marcosdione/index.html +++ b/marcosdione/index.html @@ -26,7 +26,7 @@ Soy de Córdoba, Córdoba (una es la ciudad, la otra la provincia, en ese orden, no vayan a confundir). Licenciado en Cs. de la Computación, FaMAF, UNC, 2004. Llev"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/marcosvanetta/index.html b/marcosvanetta/index.html index 207665cd1..932292678 100644 --- a/marcosvanetta/index.html +++ b/marcosvanetta/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/marianodraghi/index.html b/marianodraghi/index.html index 1fc02a2b7..8f79dcc8e 100644 --- a/marianodraghi/index.html +++ b/marianodraghi/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/marianogarcia/index.html b/marianogarcia/index.html index 83f454855..8ef174e58 100644 --- a/marianogarcia/index.html +++ b/marianogarcia/index.html @@ -26,7 +26,7 @@ Email: garcia.berrotaran AT SPAMFREE gmail DOT com Vivo en Córdoba Actualmente trabajo como Web Developer. En la oficina programo en PHP / Javascript / Java y en mi casa en Python."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/marianoguerra/index.html b/marianoguerra/index.html index 638bb61e3..17622a355 100644 --- a/marianoguerra/index.html +++ b/marianoguerra/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/marianomara/index.html b/marianomara/index.html index 878200966..7fc57cc8a 100644 --- a/marianomara/index.html +++ b/marianomara/index.html @@ -31,7 +31,7 @@ Empecé con Python en 2007, educandome con mucha lectura y algo de prá"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/marianoreingart/index.html b/marianoreingart/index.html index acc4b134e..6559421ed 100644 --- a/marianoreingart/index.html +++ b/marianoreingart/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/marianoverdu/index.html b/marianoverdu/index.html index 3572ac06f..ddbd20a49 100644 --- a/marianoverdu/index.html +++ b/marianoverdu/index.html @@ -28,7 +28,7 @@ http://www.verdumariano.com.ar/ http://www.sewebs.com/"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/martinalderete/index.html b/martinalderete/index.html index 7c8d2b313..8d353fd82 100644 --- a/martinalderete/index.html +++ b/martinalderete/index.html @@ -27,7 +27,7 @@ Simplemente me enamore de python ;). Soy Core develo"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/martinchikilian/index.html b/martinchikilian/index.html index 98c28fd54..40cf8926a 100644 --- a/martinchikilian/index.html +++ b/martinchikilian/index.html @@ -26,7 +26,7 @@ Email: martin.chikilian AT SPAMFREE gmail DOT com You can even more obfuscate your email address by adding more uppercase letters followed by a leading and trailing blank. Hac"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/martincontemacdonell/index.html b/martincontemacdonell/index.html index 6e1c4af35..fddd0f91a 100644 --- a/martincontemacdonell/index.html +++ b/martincontemacdonell/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/martingaitan/index.html b/martingaitan/index.html index 37d3fa939..cf90e7f69 100644 --- a/martingaitan/index.html +++ b/martingaitan/index.html @@ -33,7 +33,7 @@ En twitter soy @tin_nqn_ En LinkedIn"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/martinvolpe/index.html b/martinvolpe/index.html index 211ab34c2..3061497bc 100644 --- a/martinvolpe/index.html +++ b/martinvolpe/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/material/index.html b/material/index.html index 1bf45d897..897f49fa0 100644 --- a/material/index.html +++ b/material/index.html @@ -30,7 +30,7 @@ Folletos De uso general 01 (por Cesar '> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + @@ -97,7 +97,7 @@

    Material

    Doble, a color y blanco y negro (por Facundo Batista):

    Con algunos cambios: - Viene con un micro-tutorial de python.

    Este archivo utiliza el font , que puede instalarse en ubuntu asi:

    -
    sudo apt-get install ttf-dejavu
    +
    sudo apt-get install ttf-dejavu
     

    ¿Que son los tracebacks (trazas de rastreo)?

    Las trazas de rastreo (Traceback en inglés) es la información que reúne el lenguaje para informarnos sobre una excepción que ha ocurrido.

    Por ejemplo:

    -
    Traceback (most recent call last):
    -  File "form.py", line 78, in <module>
    -    f = Form("factura.csv")
    -  File "form.py", line 12, in __init__
    -    for linea in open(infile).readlines():
    -IOError: [Errno 2] No such file or directory: 'factura.csv'
    +
    Traceback (most recent call last):
    +  File "form.py", line 78, in <module>
    +    f = Form("factura.csv")
    +  File "form.py", line 12, in __init__
    +    for linea in open(infile).readlines():
    +IOError: [Errno 2] No such file or directory: 'factura.csv'
     

    Se traduciría a:

    -
    Traza de rastreo (llamada más reciente a lo último):
    -  Archivo "form.py", línea 78, en <módulo>
    -    f = Form("factura.csv")
    -  Archivo "form.py", línea 12, en __init__
    -    for linea in open(infile).readlines():
    -IOError: [Errno 2] No existe el archivo o directorio: 'factura.csv'
    +
    Traza de rastreo (llamada más reciente a lo último):
    +  Archivo "form.py", línea 78, en <módulo>
    +    f = Form("factura.csv")
    +  Archivo "form.py", línea 12, en __init__
    +    for linea in open(infile).readlines():
    +IOError: [Errno 2] No existe el archivo o directorio: 'factura.csv'
     

    Y nos dice que:

      @@ -127,47 +127,47 @@

      Mensajes Excepcionales

      En Python es fundamental dejar sangría (espacio antes de las instrucciones), que identifica el bloque al que pertenece, ya que no usamos llaves o palabras clave para delimitar los bloques como en otros lenguajes. Si bien esto ayuda a escribir código más prolijo evitando errores de anidación, puede ser raro hasta que uno se acostumbra.

      Generalmente, cada vez que abramos un bloque (con una sentencia que termina en : -dos puntos- ), debemos incrementar la sangría. Por ej:

      -
      def mayor(param1, param2=0):
      -    if param1 is None:
      -        return "El valor es None=Nulo! :S"
      -    elif param1>param2:
      -        print param1,"es mayor a", param2
      -        return "todo bien :)"
      -    else:
      -        print param1,"es menor a", param2
      -        return "todo mal :("
      -
      -print mayor(5)
      +
      def mayor(param1, param2=0):
      +    if param1 is None:
      +        return "El valor es None=Nulo! :S"
      +    elif param1>param2:
      +        print param1,"es mayor a", param2
      +        return "todo bien :)"
      +    else:
      +        print param1,"es menor a", param2
      +        return "todo mal :("
      +
      +print mayor(5)
       

      Que puede pasar si no lo hacemos...

      Error de Sangría: se esperaba un bloque con sangría

      -
      >>> if True:
      -... print "verdad!"
      -  File "<input>", line 2
      -    print "verdad!"
      -        ^
      -IndentationError: expected an indented block
      +
      >>> if True:
      +... print "verdad!"
      +  File "<input>", line 2
      +    print "verdad!"
      +        ^
      +IndentationError: expected an indented block
       

      Aquí el print esta a la misma altura que el if (sin sangría), cuando deberíamos haber dejado el espacio correspondiente porque estamos abriendo un nuevo bloque con :

      Error de Sangría: sangría no esperada

      -
      >>> print "hola"
      ->>>    print "chau"
      -  File "<input>", line 1
      -    print "chau"
      -   ^
      -IndentationError: unexpected indent
      +
      >>> print "hola"
      +>>>    print "chau"
      +  File "<input>", line 1
      +    print "chau"
      +   ^
      +IndentationError: unexpected indent
       

      Aquí el print "chau" no esta a la misma altura que el print "hola", como no abrimos un bloque con :, no es necesario dejar espacio para la sangría.

      Error de Sangría: la nueva sangría no coincide con ningún otro nivel exterior

      -
      >>> def prueba():
      -...     if False:
      -...         pass
      -...   print "..."
      -  File "<input>", line 4
      -    print "..."
      -
      -^
      -IndentationError: unindent does not match any outer indentation level
      +
      >>> def prueba():
      +...     if False:
      +...         pass
      +...   print "..."
      +  File "<input>", line 4
      +    print "..."
      +
      +^
      +IndentationError: unindent does not match any outer indentation level
       

      Aquí el print "..." no esta a la misma altura que el if False ni que el pass ni que el def, por lo que no se sabe a que bloque pertenece. Si cerramos el bloque del if debería estar a la misma altura que este, y si pertenece al bloque if, debería estar dentro de este a la altura del pass. Si el print no pertenece a la función, deberíamos ponerlo a la misma altura que el def

    Errores de Sintaxis (SyntaxError)

    @@ -256,71 +256,71 @@

    Mensajes Excepcionales

    Esperando no haberlo abrumado con el resumen de la sintaxis del lenguaje (los interesados pueden ver la especificación completa en http://docs.python.org/), veamos que pasa si no la respetamos:

    Error de Sintaxis: sintaxis inválida

    -
    >>> If a>1:
    -  File "<input>", line 1
    -    If a>1:
    -       ^
    -SyntaxError: invalid syntax
    +
    >>> If a>1:
    +  File "<input>", line 1
    +    If a>1:
    +       ^
    +SyntaxError: invalid syntax
     

    Python respeta mayúsculas y minusculas, If no es el if que queremos usar. Tener cuidado sobre todo si venimos de lenguajes que son indiferentes a este tema (por. ej. Visual Basic)

    -
    >>> secuencia = 1 2
    -  File "<input>", line 1
    -    secuencia = 1 2
    -                  ^
    -SyntaxError: invalid syntax
    +
    >>> secuencia = 1 2
    +  File "<input>", line 1
    +    secuencia = 1 2
    +                  ^
    +SyntaxError: invalid syntax
     

    Debemos indicar un operador entre las expresiones o un delimitador entre los elementos. En este caso nos falto la coma secuencia = 1, 2

    -
    >>> if a==1
    -...    print "a es verdadero!"
    -  File "<input>", line 1
    -    if a==1
    -
    -^
    -SyntaxError: invalid syntax
    +
    >>> if a==1
    +...    print "a es verdadero!"
    +  File "<input>", line 1
    +    if a==1
    +
    +^
    +SyntaxError: invalid syntax
     

    Las sentencias compuestas, deben terminar con dos puntos (":") para indicar el nuevo bloque que afectan if a==1:

    -
    >>> while a=1:
    -  File "<input>", line 1
    -    while a=1:
    -           ^
    -SyntaxError: invalid syntax
    +
    >>> while a=1:
    +  File "<input>", line 1
    +    while a=1:
    +           ^
    +SyntaxError: invalid syntax
     

    La asignación no se puede usar en una expresión (comparación), por ej., para evitar los errores clásicos en C while(v=1)... donde nos asignaba 1 a v en vez de comparar si v era igual a 1. En este caso, usar el operador de comparación while a==1:

    -
    >>> def a:
    -  File "<input>", line 1
    -    def a:
    -         ^
    -SyntaxError: invalid syntax
    +
    >>> def a:
    +  File "<input>", line 1
    +    def a:
    +         ^
    +SyntaxError: invalid syntax
     

    Por más que no tengamos parámetros en nuestra función, los paréntesis son obligatorios. Sería: def a():

    Error de Sintaxis: FinDeLinea mientras se buscaba una cadena "simple"

    -
    >>> 'abc"
    -  File "<input>", line 1
    -    'abc"
    -        ^
    -SyntaxError: EOL while scanning single-quoted string
    +
    >>> 'abc"
    +  File "<input>", line 1
    +    'abc"
    +        ^
    +SyntaxError: EOL while scanning single-quoted string
     

    Las cadenas simples (de una sola línea) deben empezar y terminar en la misma línea y con el mismo caracter, comillas (") o tilde (').

    Error de Sintaxis: FinDeArchivo mientras se buscaba una cadena de "múltiples líneas"

    -
    >>> """
    -... mucho
    -... texto
    -...
    -SyntaxError: EOF while scanning triple-quoted string
    +
    >>> """
    +... mucho
    +... texto
    +...
    +SyntaxError: EOF while scanning triple-quoted string
     

    Las cadenas de múltiples líneas, deben empezar con triple comilla o tilde, y terminar con lo mismo. Aquí faltó cerrar la cadena con """ Nota: el error es simulado, es difícil que suceda en el intérprete, pero si ocurre en un archivo)

    Error de Sintaxis: no es posible asignar a un operador

    -
    >>> numero+antiguo=1
    -  File "<input>", line 1
    -SyntaxError: can't assign to operator (<input>, line 1)
    +
    >>> numero+antiguo=1
    +  File "<input>", line 1
    +SyntaxError: can't assign to operator (<input>, line 1)
     

    El nombre de la variable es inválido, sería: numero_mas_antiguo=1

    Error de Sintaxis: "token" inválido

    -
    >>> print 08
    -  File "<stdin>", line 1
    -    print 08
    -           ^
    -SyntaxError: invalid token
    +
    >>> print 08
    +  File "<stdin>", line 1
    +    print 08
    +           ^
    +SyntaxError: invalid token
     

    El compilador de Python es muy estricto, y si no recibe el símbolo/componente léxico correcto ("token") nos emitirá estos errores. En este caso, se debe a que los numeros que comienzan con 0 es un caso especial de notación octal (base 8), por lo que solo acepta números del 0 al 7. Para corregir el error, eliminar el 0 que precede al número print 8

    Errores de Nombres (NameError)

    @@ -331,43 +331,43 @@

    Mensajes Excepcionales

    O sea, previamente debimos haberle asignado un valor a una variable (con =), definido una función con def o clase con class. Tener en cuenta que Python justamente es dinámico, y si el interprete no pasa por la linea de la definición, no se define, por más que este el código en el archivo.

    En otros lenguajes, si la variable no esta definida, a veces toma un valor arbitrario (nulo, 0 o cadena vacia) o queda declarada sin inicializar (tomando cualquier valor que esté en la memoria), con los consiguientes errores que esto puede ocasionar. Para prevenir esto, en Python es necesario explicitamente definir ("inicializar") la variable con un valor inicial.

    Error de Nombre: el nombre 'variable' no está definido

    -
    >>> saludo="Hola"
    ->>> print Saludo
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -NameError: name 'Saludo' is not defined
    +
    >>> saludo="Hola"
    +>>> print Saludo
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +NameError: name 'Saludo' is not defined
     

    Estamos queriendo usar un nombre (identificador) de algo que no existe. En este caso la variable Saludo no está inicializada, ya que el nombre de variable correcta es saludo (notar la diferencia de mayúsculas y minúsculas que comentamos en la sección anterior)

    Error de Nombre: el nombre global 'variable' no está definido

    -
    >>> def mi_func():
    -...     print variable
    -...
    ->>> mi_func()
    -Traceback (most recent call last):
    -  File "<stdin>", line 1, in <module>
    -  File "<stdin>", line 2, in mi_func
    -NameError: global name 'variable' is not defined
    ->>>
    +
    >>> def mi_func():
    +...     print variable
    +...
    +>>> mi_func()
    +Traceback (most recent call last):
    +  File "<stdin>", line 1, in <module>
    +  File "<stdin>", line 2, in mi_func
    +NameError: global name 'variable' is not defined
    +>>>
     

    Similar al anterior, estamos queriendo usar una variable que no definimos previamente (ahora dentro de una función). O definimos la variable globalmente (fuera de la función), o localmente (dentro de la función).

    Error de no vinculación local: la variable local 'xxx' fue referenciada antes de asignarla

    -
    >>> variable = 1
    ->>> def mi_func():
    -...     print variable
    -...     variable = variable + 1
    -...
    ->>> mi_func()
    -Traceback (most recent call last):
    -  File "<stdin>", line 1, in <module>
    -  File "<stdin>", line 2, in mi_func
    -UnboundLocalError: local variable 'variable' referenced before assignment
    +
    >>> variable = 1
    +>>> def mi_func():
    +...     print variable
    +...     variable = variable + 1
    +...
    +>>> mi_func()
    +Traceback (most recent call last):
    +  File "<stdin>", line 1, in <module>
    +  File "<stdin>", line 2, in mi_func
    +UnboundLocalError: local variable 'variable' referenced before assignment
     

    Una variación del anterior, pero en este caso, debemos usar la sentencia global variable dentro de la función, ya que, sinó, al asignarle un valor dentro de la función, se convierte automáticamente en una variable local, por más que exista globalmente (y da error si la asignación no está al principio de la función antes de usar la variable):

    -
    variable = 1
    -def mi_func():
    -    global variable
    -    print variable
    -    variable = variable + 1
    +
    variable = 1
    +def mi_func():
    +    global variable
    +    print variable
    +    variable = variable + 1
     

    Errores de Tipos (TypeError)

    @@ -376,162 +376,162 @@

    Mensajes Excepcionales

    Si si, Python es fuertemente tipado, en general no hará mágia con nuestros datos para convertirlos de un tipo a otro, si no se lo pedimos explícitamente.

    No como en otros lenguajes, que cambiarían el tipo de una variable silenciosamente dependiendo del contexto (que puede ser ambiguo, por ej. ¿convertir a float o int?) con el consiguiente arrastre de un error difícil de solucionar.

    Error de Tipo: tipo de operando no soportado para +: 'int' y 'str'

    -
    >>> a = 5
    ->>> b = "10"
    ->>> a+b
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -TypeError: unsupported operand type(s) for +: 'int' and 'str'
    +
    >>> a = 5
    +>>> b = "10"
    +>>> a+b
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +TypeError: unsupported operand type(s) for +: 'int' and 'str'
     

    Típico, en algunos lenguajes esto puede resultar "510" o 15 (dependiendo como entienda el contexto, el órden de los operandos, etc.) ya que hacen una conversión de tipos implícita.

    En Python, gentilmente nos avisa que, explicitamente debemos convertir el número a cadena (str(a)+b que resulta en "510") o la cadena en número (a+int(b) que resulta en 15.

    Error de Tipo: se requiere un entero

    -
    >>> fecha = datetime.date('2010','05','10')
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -TypeError: an integer is required
    +
    >>> fecha = datetime.date('2010','05','10')
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +TypeError: an integer is required
     

    Algunas funciones validan los parámetros de entrada, en este caso datetime.date solicita enteros. Sería datetime.date(int('2010'),int('05'),int('10'))

    Error de Tipo: el objeto 'NoneType' no es iterable

    -
    >>> secuencia = None
    ->>> for i in secuencia:
    -...     pass
    -...
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -TypeError: 'NoneType' object is not iterable
    +
    >>> secuencia = None
    +>>> for i in secuencia:
    +...     pass
    +...
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +TypeError: 'NoneType' object is not iterable
     

    Para iterar (recorrer uno a uno los elementos de una secuencia o colección), por ej. en un for, es necesario que esta sea realmente una secuencia o iterable (tuplas, listas, diccionario, conjunto, etc.)

    Funciones

    Podemos tener errores de tipo o de sintaxis respecto a las funciones, por ejemplo:

    Error de Tipo: objeto 'int' no es llamable

    -
    >>> a=1
    ->>> a (1)
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -TypeError: 'int' object is not callable
    +
    >>> a=1
    +>>> a (1)
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +TypeError: 'int' object is not callable
     

    Estamos queriendo llamar a una variable que tiene un entero, cosa que no se puede (no es una "función llamable"). Seguramente, o la variable no debería haber sido un entero, o en vez de llamarla deberíamos aplicar algún operador o método sobre ella.

    Error de Tipo: función() toma al menos un argumento (0 dados)

    -
    >>> mayor()
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -TypeError: mayor() takes at least 1 argument (0 given)
    +
    >>> mayor()
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +TypeError: mayor() takes at least 1 argument (0 given)
     

    Al definir la función, dijimos que tenía dos parámetros (param1 y param2=0). Salvo que el parámetro tenga un valor por defecto (en el caso de param2 es 0), debemos pasarlo al llamar a la función. Revisar...

    Error de Tipo: función() toma como mucho 2 argumentos (3 dados)

    -
    >>> mayor(5,5,5)
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -TypeError: mayor() takes at most 2 arguments (3 given)
    +
    >>> mayor(5,5,5)
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +TypeError: mayor() takes at most 2 arguments (3 given)
     

    Similar al anterior, pero le pasamos más parámetros de los que necesita la función. Revisar...

    Error de Tipo: función() tuvo un argumento por nombre inesperado 'paramx'

    -
    >>> mayor(param3=5)
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -TypeError: mayor() got an unexpected keyword argument 'param3'
    +
    >>> mayor(param3=5)
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +TypeError: mayor() got an unexpected keyword argument 'param3'
     

    Idem al anterior, tratamos de pasarle un parámetro (esta vez por nombre), que tampoco esta definido en la misma. Revisar....

    Error de Sintáxis: argumento por posición luego de argumento por nombre

    -
    >>> mayor(param2=5,3)
    -  File "<input>", line 1
    -SyntaxError: non-keyword arg after keyword arg (<input>, line 1)
    +
    >>> mayor(param2=5,3)
    +  File "<input>", line 1
    +SyntaxError: non-keyword arg after keyword arg (<input>, line 1)
     

    Los parámetros por posición se pasan antes que los parámetros por nombre: mayor(3,param2=5)

    Errores de Valores (ValueError)

    De manera similar a los errores de tipos, cuando pasemos un dato que no se puede convertir o es inválido, Python nos mostrará estos mensajes:

    Error de Valor: literal inválido para int() con base 10: 'xxxx'

    -
    >>> int("10ab")
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -ValueError: invalid literal for int() with base 10: '10ab'
    +
    >>> int("10ab")
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +ValueError: invalid literal for int() with base 10: '10ab'
     

    En este caso '10ab', salvo que las letras sean un error te escritura, estamos intentando convertir un valor hexadecimal (base 16) a entero, sin especificarlo, por lo que intenta base 10 por defecto. Lo correcto sería int("10ab",16)

    Igualmente siempre es conveniente capturar este tipo de errores, para validar que el dato a convertir es realmente un número, y sinó, tomar una medida adecuada.

    Error de Valor: literal inválido para float() con base 10: 'xxxx'

    -
    >>> float("10,50")
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -ValueError: invalid literal for float(): 10,50
    +
    >>> float("10,50")
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +ValueError: invalid literal for float(): 10,50
     

    Lo mismo que el anterior, pero con la salvedad que para python debemos indicar los decimales con el punto (.) y no la coma (,). Podríamos convertirlo facilmente: float("10,50".replace(",",".")

    Error de Valor: el día esta fuera de rango para el mes

    -
    >>> fecha = datetime.date(10,5,2010)
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -ValueError: day is out of range for month
    +
    >>> fecha = datetime.date(10,5,2010)
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +ValueError: day is out of range for month
     

    Estamos intentando pasar un valor a la función en el parámetro que no corresponde: datetime.date(año, mes, día) Sería fecha = datetime.date(2010,5,10)

    Error de Valor: demasiados valores para desempaquetar

    -
    >>> a,b,c = (1,2,3,4)
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -ValueError: too many values to unpack
    +
    >>> a,b,c = (1,2,3,4)
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +ValueError: too many values to unpack
     

    En Python, podemos asignar varios elementos a una lista de destinos, pero la cantidad de destinos y de elementos a asignar deben coincidir. En este caso, a=1, b=2, c=3 y al cuarto elemento ya no hay a que asignarlo. Podríamos agregar un destino más: a,b,c,d = (1,2,3,4) o sacar un elemento a asignar de la expresión: a,b,c = (1,2,3).

    Error de Valor: necesita más de 2 valores para desempaquetar

    -
    >>> x,y,z = 1, 2
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -ValueError: need more than 2 values to unpack
    +
    >>> x,y,z = 1, 2
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +ValueError: need more than 2 values to unpack
     

    Caso inverso al anterior, nos falta un elemento en la expresión de asignación (o nos sobra un destino). Posible solución: sacamos un destino x,y = 1, 2 o agregamos un elemento: x,y,< = 1, 2 ,3

    Error de Valor: caracter de escape x inválido

    -
    >>> open("C:\xaraza.txt")
    -ValueError: invalid \x escape
    +
    >>> open("C:\xaraza.txt")
    +ValueError: invalid \x escape
     

    En los strings (cadenas), ciertos caracteres tienen un significado especial. Es el caso de la barra invertida (""), que identifica que lo que sigue definie un caractér especial ("n" para el salto de linea, "xfe" para el caracter cuyo código hexadecimal es FE, etc.) Si queremos una barra invertida (por ejemplo, en un directorio de windows), debemos usar strings crudos (raws): r"C:xaraza.txt" o doble barra invertida: "C:\xaraza.txt"

    Errores de Atributos (AttributeError)

    Practicamente todo en Python es un objeto, y estos objetos tienen métodos y "propiedades" (ambos denominados atributos). Si intentamos acceder a un atributo que no pertenece al objeto, se producirá uno de los siguientes errores:

    Error de Atributo: el objeto 'NoneType' no tiene el atributo 'split'

    -
    >>> fecha = None
    ->>> fecha.split("/")
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -AttributeError: 'NoneType' object has no attribute 'split'
    +
    >>> fecha = None
    +>>> fecha.split("/")
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +AttributeError: 'NoneType' object has no attribute 'split'
     

    En este caso estamos queriendo invocar a un método split que no esta definido para este tipo de objeto (aquí None, pero podría ser cualquier otro). Seguramente la variable fecha debería ser otra cosa, o nos equivocamos de método a invocar.

    Error de Atributo: el objeto 'modulo' no tiene el atributo 'next'

    -
    >>> import csv
    ->>> csv.next()
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -AttributeError: 'module' object has no attribute 'next'
    +
    >>> import csv
    +>>> csv.next()
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +AttributeError: 'module' object has no attribute 'next'
     

    Similar al anterior, pero en este caso estamos importando un módulo csv que no tiene la función next}. En este caso particular, next es un método de la instancia de csv_reader, no del módulo.

    Errores de Índice (IndexError)

    Error de Índice: el índice de lista esta fuera de rango

    -
    >>> l=[1,2,3]
    ->>> l[3]
    -Traceback (most recent call last):
    -  File "<stdin>", line 1, in <module>
    -IndexError: list index out of range
    +
    >>> l=[1,2,3]
    +>>> l[3]
    +Traceback (most recent call last):
    +  File "<stdin>", line 1, in <module>
    +IndexError: list index out of range
     

    En este caso, la lista tiene 3 elementos, y se acceden desde la posición 0 hasta la 3 (como en C), lo correcto sería l[2] para el tercer elemento.

    Errores de Clave (KeyError)

    Los diccionarios se acceden por clave asociativa, si la clave no existe, se producirá un error:

    -
    >>> dict = {'clave': 'valor'}
    ->>> dict['clave2']
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -KeyError: 'clave2'
    +
    >>> dict = {'clave': 'valor'}
    +>>> dict['clave2']
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +KeyError: 'clave2'
     

    En este caso, podríamos acceder al valor de correcto usando dict['clave'] que sí existe, o pedir dict.get('clave2') que si la clave no existe, devolverá None y no producirá una excepción.

    Otros Errores

    Los errores del sistema operativo y bibliotecas relacionadas también se expresan como excepciones:

    IOError: [Errno 2] No existe el archivo o directorio: 'C:\saraza'

    -
    >>> open("C:\saraza")
    -Traceback (most recent call last):
    -  File "<input>", line 1, in <module>
    -IOError: [Errno 2] No such file or directory: 'C:\\saraza'
    +
    >>> open("C:\saraza")
    +Traceback (most recent call last):
    +  File "<input>", line 1, in <module>
    +IOError: [Errno 2] No such file or directory: 'C:\\saraza'
     

    El archivo solicitado no existe, si queremos crearlo deberíamos pasarle un segundo parámetro que lo especifique: open("saraza","a") o open("saraza","w")

    Advertencias

    Como comentabamos, hay Excepciones que no son errores, sino advertencias. Se usan para avisarnos sobre algún cambio en el lenguaje o código potencialmente incorrecto o perjudicial:

    Advertencia de "Deprecación": el módulo md5 esta desaconsejado; use en su lugar haslib

    -
    >>> import md5
    -__main__:1: DeprecationWarning: the md5 module is deprecated; use hashlib instead
    +
    >>> import md5
    +__main__:1: DeprecationWarning: the md5 module is deprecated; use hashlib instead
     

    En esta versión de Python, el módulo md5 existe por compatibilidad hacia atrás. En versiones posteriores podría no existir más. Se recomienda revisar la recomendación que nos da Python: el módulo hashlib.

    diff --git a/merchandisingpyconar2011/index.html b/merchandisingpyconar2011/index.html index 908631f06..1e45b3a09 100644 --- a/merchandisingpyconar2011/index.html +++ b/merchandisingpyconar2011/index.html @@ -26,7 +26,7 @@ Para Pyconar 2011 vamos a hacer que elijas uno de los regalos ( seran varios ? ) que te gustaría llevarte del evento. ¿ Te gusta el merc"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    diff --git a/miembros/2immarketing/index.html b/miembros/2immarketing/index.html index ea0fcde55..de5b382b4 100644 --- a/miembros/2immarketing/index.html +++ b/miembros/2immarketing/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/acondori/index.html b/miembros/acondori/index.html index 85acc957f..506b7937f 100644 --- a/miembros/acondori/index.html +++ b/miembros/acondori/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/agustin92/index.html b/miembros/agustin92/index.html index e2ed4fca9..bbe98b380 100644 --- a/miembros/agustin92/index.html +++ b/miembros/agustin92/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/alejandra/index.html b/miembros/alejandra/index.html index a7256fb0d..99792db15 100644 --- a/miembros/alejandra/index.html +++ b/miembros/alejandra/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/alejandro_0101/index.html b/miembros/alejandro_0101/index.html index 390f0fad6..396464d29 100644 --- a/miembros/alejandro_0101/index.html +++ b/miembros/alejandro_0101/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/amjalca/index.html b/miembros/amjalca/index.html index 7b7e438b7..0936ce51e 100644 --- a/miembros/amjalca/index.html +++ b/miembros/amjalca/index.html @@ -27,7 +27,7 @@ Twitter: AT SPAMFREE amjalca Email: heyamjalca AT SPAMFREE gmail DOT com"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/miembros/andres14/index.html b/miembros/andres14/index.html index 0a0afdabf..1b3275fe0 100644 --- a/miembros/andres14/index.html +++ b/miembros/andres14/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/andresdevops/index.html b/miembros/andresdevops/index.html index b0af24494..69b72bf86 100644 --- a/miembros/andresdevops/index.html +++ b/miembros/andresdevops/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/armando/index.html b/miembros/armando/index.html index fa425fe91..039cecf87 100644 --- a/miembros/armando/index.html +++ b/miembros/armando/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/becerra1982/index.html b/miembros/becerra1982/index.html index 6587203c9..78fe61dfb 100644 --- a/miembros/becerra1982/index.html +++ b/miembros/becerra1982/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/benjapy/index.html b/miembros/benjapy/index.html index b5330711b..61ed7e4bc 100644 --- a/miembros/benjapy/index.html +++ b/miembros/benjapy/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/bgeninatti/index.html b/miembros/bgeninatti/index.html index fc4f88777..e4e47f01a 100644 --- a/miembros/bgeninatti/index.html +++ b/miembros/bgeninatti/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/btenaglia/index.html b/miembros/btenaglia/index.html index da66c169c..b59181bc1 100644 --- a/miembros/btenaglia/index.html +++ b/miembros/btenaglia/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/buongarzoni/index.html b/miembros/buongarzoni/index.html index 6723ffa6c..d00ad0e93 100644 --- a/miembros/buongarzoni/index.html +++ b/miembros/buongarzoni/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/carasucia/index.html b/miembros/carasucia/index.html index 7222bf9f2..b4535a8b3 100644 --- a/miembros/carasucia/index.html +++ b/miembros/carasucia/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/carloscarlossouthpalscom/index.html b/miembros/carloscarlossouthpalscom/index.html index 2ebfee613..d608fd4c1 100644 --- a/miembros/carloscarlossouthpalscom/index.html +++ b/miembros/carloscarlossouthpalscom/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/centertek/index.html b/miembros/centertek/index.html index f2378704d..c2c827d3d 100644 --- a/miembros/centertek/index.html +++ b/miembros/centertek/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/cesarroldan/index.html b/miembros/cesarroldan/index.html index 18b446ca0..3dccdb56a 100644 --- a/miembros/cesarroldan/index.html +++ b/miembros/cesarroldan/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/cmenta/index.html b/miembros/cmenta/index.html index 115b93dc8..969ca9e17 100644 --- a/miembros/cmenta/index.html +++ b/miembros/cmenta/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/correanicolas/index.html b/miembros/correanicolas/index.html index 24b59233a..1a674ab26 100644 --- a/miembros/correanicolas/index.html +++ b/miembros/correanicolas/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/crisovando/index.html b/miembros/crisovando/index.html index c924d636a..30de3cab6 100644 --- a/miembros/crisovando/index.html +++ b/miembros/crisovando/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/danis/index.html b/miembros/danis/index.html index bfb27ef9e..007690ac0 100644 --- a/miembros/danis/index.html +++ b/miembros/danis/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/danymana/index.html b/miembros/danymana/index.html index 1c0c10739..767cedb78 100644 --- a/miembros/danymana/index.html +++ b/miembros/danymana/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/debianitram/index.html b/miembros/debianitram/index.html index cad4a41bb..7ca0b60b3 100644 --- a/miembros/debianitram/index.html +++ b/miembros/debianitram/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/debrivero/index.html b/miembros/debrivero/index.html index e9322bf2e..a995aa3c0 100644 --- a/miembros/debrivero/index.html +++ b/miembros/debrivero/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/dgonzalez/index.html b/miembros/dgonzalez/index.html index 1cc2edaf4..0ca48c9a8 100644 --- a/miembros/dgonzalez/index.html +++ b/miembros/dgonzalez/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/diegoduncan21/index.html b/miembros/diegoduncan21/index.html index 1ff8c8022..b1de018d0 100644 --- a/miembros/diegoduncan21/index.html +++ b/miembros/diegoduncan21/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/dnc91/index.html b/miembros/dnc91/index.html index 17794721a..fec82558c 100644 --- a/miembros/dnc91/index.html +++ b/miembros/dnc91/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/edwinr2000/index.html b/miembros/edwinr2000/index.html index b2030c0d0..366d5abcc 100644 --- a/miembros/edwinr2000/index.html +++ b/miembros/edwinr2000/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/ekimal/index.html b/miembros/ekimal/index.html index 0dc4bece3..2e56e6037 100644 --- a/miembros/ekimal/index.html +++ b/miembros/ekimal/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/eliobastias/index.html b/miembros/eliobastias/index.html index 25930635a..1320709e2 100644 --- a/miembros/eliobastias/index.html +++ b/miembros/eliobastias/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/empoisoner/index.html b/miembros/empoisoner/index.html index af7277f8e..491015725 100644 --- a/miembros/empoisoner/index.html +++ b/miembros/empoisoner/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/ernestto/index.html b/miembros/ernestto/index.html index c6ade5fa9..7ccefbaf1 100644 --- a/miembros/ernestto/index.html +++ b/miembros/ernestto/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/facundobatista/index.html b/miembros/facundobatista/index.html index a998845a2..1160618ef 100644 --- a/miembros/facundobatista/index.html +++ b/miembros/facundobatista/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/miembros/falcho/index.html b/miembros/falcho/index.html index 3649e3877..ca51b2880 100644 --- a/miembros/falcho/index.html +++ b/miembros/falcho/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/fausto10/index.html b/miembros/fausto10/index.html index 96ba9ebc0..b4b207582 100644 --- a/miembros/fausto10/index.html +++ b/miembros/fausto10/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/ferjavrec/index.html b/miembros/ferjavrec/index.html index 520f7da4e..4b250a89b 100644 --- a/miembros/ferjavrec/index.html +++ b/miembros/ferjavrec/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/fernandolamasw/index.html b/miembros/fernandolamasw/index.html index 1d0afb28c..654b3229f 100644 --- a/miembros/fernandolamasw/index.html +++ b/miembros/fernandolamasw/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/fideo/index.html b/miembros/fideo/index.html index b5584e288..984107187 100644 --- a/miembros/fideo/index.html +++ b/miembros/fideo/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/franco_jerke/index.html b/miembros/franco_jerke/index.html index 7a1b69cb7..b7e9e3036 100644 --- a/miembros/franco_jerke/index.html +++ b/miembros/franco_jerke/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/frobriel/index.html b/miembros/frobriel/index.html index 024e009d5..af58cd242 100644 --- a/miembros/frobriel/index.html +++ b/miembros/frobriel/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/fullpaint/index.html b/miembros/fullpaint/index.html index b57047a0b..cb16d2f0e 100644 --- a/miembros/fullpaint/index.html +++ b/miembros/fullpaint/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/gavalen/index.html b/miembros/gavalen/index.html index 1bbc6150c..9a3c66612 100644 --- a/miembros/gavalen/index.html +++ b/miembros/gavalen/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/gbaume/index.html b/miembros/gbaume/index.html index a42db441e..7b53ad414 100644 --- a/miembros/gbaume/index.html +++ b/miembros/gbaume/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/gilgamezh/index.html b/miembros/gilgamezh/index.html index 3c0000f27..74c2d8fff 100644 --- a/miembros/gilgamezh/index.html +++ b/miembros/gilgamezh/index.html @@ -26,7 +26,7 @@ Blog: http://gilgamezh.me/blog Actualmente vivo en CABA y trabajo en sistemas desde el Y2K. Sysadmin/WebOps/SRE/etc. Estudiante truncado de Sistemas. Me gusta mucho tra"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/miembros/ginomarcellino/index.html b/miembros/ginomarcellino/index.html index c38d7b9c6..ecdba1dc7 100644 --- a/miembros/ginomarcellino/index.html +++ b/miembros/ginomarcellino/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/guido/index.html b/miembros/guido/index.html index fefcf5758..3f27ce5d7 100644 --- a/miembros/guido/index.html +++ b/miembros/guido/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/gustavofurlan/index.html b/miembros/gustavofurlan/index.html index 8b66ed358..f70cc336c 100644 --- a/miembros/gustavofurlan/index.html +++ b/miembros/gustavofurlan/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/hatsem78/index.html b/miembros/hatsem78/index.html index ae712f051..cb264207b 100644 --- a/miembros/hatsem78/index.html +++ b/miembros/hatsem78/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/herchila/index.html b/miembros/herchila/index.html index e5c041756..30c940871 100644 --- a/miembros/herchila/index.html +++ b/miembros/herchila/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/humitos/index.html b/miembros/humitos/index.html index 31afb5d86..77211da7a 100644 --- a/miembros/humitos/index.html +++ b/miembros/humitos/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/idoneus/index.html b/miembros/idoneus/index.html index 6a10cbf3e..233313b96 100644 --- a/miembros/idoneus/index.html +++ b/miembros/idoneus/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/ignacionicolasalvarez/index.html b/miembros/ignacionicolasalvarez/index.html index 955703485..b3b248df6 100644 --- a/miembros/ignacionicolasalvarez/index.html +++ b/miembros/ignacionicolasalvarez/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/inafontan/index.html b/miembros/inafontan/index.html index f10c602b6..16b64d8aa 100644 --- a/miembros/inafontan/index.html +++ b/miembros/inafontan/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/inokis/index.html b/miembros/inokis/index.html index 7a8eb8a22..41747adac 100644 --- a/miembros/inokis/index.html +++ b/miembros/inokis/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/intligente/index.html b/miembros/intligente/index.html index d4d8539ce..36a38210e 100644 --- a/miembros/intligente/index.html +++ b/miembros/intligente/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/jdromero1/index.html b/miembros/jdromero1/index.html index 43d81b6dc..27c4b2fef 100644 --- a/miembros/jdromero1/index.html +++ b/miembros/jdromero1/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/jigcau89/index.html b/miembros/jigcau89/index.html index 8fad57148..2b6d3a84c 100644 --- a/miembros/jigcau89/index.html +++ b/miembros/jigcau89/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/jorgermc123/index.html b/miembros/jorgermc123/index.html index 221374e4f..f38bd28a7 100644 --- a/miembros/jorgermc123/index.html +++ b/miembros/jorgermc123/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/joseernestomoralesventura/index.html b/miembros/joseernestomoralesventura/index.html index b544a617d..e7510bcfd 100644 --- a/miembros/joseernestomoralesventura/index.html +++ b/miembros/joseernestomoralesventura/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/jotajota-2012/index.html b/miembros/jotajota-2012/index.html index 8c1c97023..3079e6b97 100644 --- a/miembros/jotajota-2012/index.html +++ b/miembros/jotajota-2012/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/jquintas/index.html b/miembros/jquintas/index.html index 0d8ae8a6a..06258c48c 100644 --- a/miembros/jquintas/index.html +++ b/miembros/jquintas/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/juanandres438/index.html b/miembros/juanandres438/index.html index ef3f05752..cd5987250 100644 --- a/miembros/juanandres438/index.html +++ b/miembros/juanandres438/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/juanpablo064/index.html b/miembros/juanpablo064/index.html index 686433e37..8e7ef04c5 100644 --- a/miembros/juanpablo064/index.html +++ b/miembros/juanpablo064/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/keyleron/index.html b/miembros/keyleron/index.html index af44ac247..839277465 100644 --- a/miembros/keyleron/index.html +++ b/miembros/keyleron/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/knonical/index.html b/miembros/knonical/index.html index 76422847f..91a54fafa 100644 --- a/miembros/knonical/index.html +++ b/miembros/knonical/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/lacpac23/index.html b/miembros/lacpac23/index.html index 54bda1dbc..3699f1285 100644 --- a/miembros/lacpac23/index.html +++ b/miembros/lacpac23/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/lucaspyar/index.html b/miembros/lucaspyar/index.html index 0cbeca78b..96a1b901b 100644 --- a/miembros/lucaspyar/index.html +++ b/miembros/lucaspyar/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/luciano1994/index.html b/miembros/luciano1994/index.html index a4cc5428a..6eeef5d2c 100644 --- a/miembros/luciano1994/index.html +++ b/miembros/luciano1994/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/martingaitan/index.html b/miembros/martingaitan/index.html index 54dc531e8..68044cf37 100644 --- a/miembros/martingaitan/index.html +++ b/miembros/martingaitan/index.html @@ -33,7 +33,7 @@ En twitter soy @tin_nqn_ En LinkedIn"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/miembros/matiasgabrieln/index.html b/miembros/matiasgabrieln/index.html index 194133e96..47bc20464 100644 --- a/miembros/matiasgabrieln/index.html +++ b/miembros/matiasgabrieln/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/matibarriento/index.html b/miembros/matibarriento/index.html index d6168316d..a7efbc4f6 100644 --- a/miembros/matibarriento/index.html +++ b/miembros/matibarriento/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/mauriciobaeza/index.html b/miembros/mauriciobaeza/index.html index 6d491e9d4..cb744ac65 100644 --- a/miembros/mauriciobaeza/index.html +++ b/miembros/mauriciobaeza/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/maurosl/index.html b/miembros/maurosl/index.html index 559f58ab5..10d2556f0 100644 --- a/miembros/maurosl/index.html +++ b/miembros/maurosl/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/mbaragiola/index.html b/miembros/mbaragiola/index.html index 4db6a27f9..96efefcd7 100644 --- a/miembros/mbaragiola/index.html +++ b/miembros/mbaragiola/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/mirlo/index.html b/miembros/mirlo/index.html index d6362d229..d397db00d 100644 --- a/miembros/mirlo/index.html +++ b/miembros/mirlo/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/mmartinovic/index.html b/miembros/mmartinovic/index.html index 9a1b1f741..0a625155e 100644 --- a/miembros/mmartinovic/index.html +++ b/miembros/mmartinovic/index.html @@ -26,7 +26,7 @@ Soy desarrollador python desde el año 2009. He trabajado con WxPython, QT, Flask... pero realmente me encanta laburar con Django."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/miembros/noeliabruscoli/index.html b/miembros/noeliabruscoli/index.html index 76186c092..1d93455a7 100644 --- a/miembros/noeliabruscoli/index.html +++ b/miembros/noeliabruscoli/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/nrivollier/index.html b/miembros/nrivollier/index.html index 3d5ea79a2..5706764a9 100644 --- a/miembros/nrivollier/index.html +++ b/miembros/nrivollier/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/numaelis/index.html b/miembros/numaelis/index.html index 6b83813dc..e871c8869 100644 --- a/miembros/numaelis/index.html +++ b/miembros/numaelis/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/miembros/oconner/index.html b/miembros/oconner/index.html index 1d8b8dfe8..c9efd066f 100644 --- a/miembros/oconner/index.html +++ b/miembros/oconner/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/pab/index.html b/miembros/pab/index.html index af48b3d02..a62c7007e 100644 --- a/miembros/pab/index.html +++ b/miembros/pab/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/pamparider/index.html b/miembros/pamparider/index.html index 4b9629f8a..9b1af6f21 100644 --- a/miembros/pamparider/index.html +++ b/miembros/pamparider/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/patricio81/index.html b/miembros/patricio81/index.html index b346d4356..788784a9a 100644 --- a/miembros/patricio81/index.html +++ b/miembros/patricio81/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/ramon27/index.html b/miembros/ramon27/index.html index b7a9a32d0..e4b503d10 100644 --- a/miembros/ramon27/index.html +++ b/miembros/ramon27/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/rbellanti/index.html b/miembros/rbellanti/index.html index 0af920e62..e8b5d9141 100644 --- a/miembros/rbellanti/index.html +++ b/miembros/rbellanti/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/salbarracin/index.html b/miembros/salbarracin/index.html index 86f0f3428..83fdb1a1a 100644 --- a/miembros/salbarracin/index.html +++ b/miembros/salbarracin/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/sam/index.html b/miembros/sam/index.html index dbb9f6d86..fb4a5fa21 100644 --- a/miembros/sam/index.html +++ b/miembros/sam/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/scrdsindia/index.html b/miembros/scrdsindia/index.html index 266956d06..9d4fd63b4 100644 --- a/miembros/scrdsindia/index.html +++ b/miembros/scrdsindia/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/sebasgiustra/index.html b/miembros/sebasgiustra/index.html index 5cf1a3dd8..324c0bc9a 100644 --- a/miembros/sebasgiustra/index.html +++ b/miembros/sebasgiustra/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/miembros/sebbasfernandez/index.html b/miembros/sebbasfernandez/index.html index cd0caace7..2af2a35cc 100644 --- a/miembros/sebbasfernandez/index.html +++ b/miembros/sebbasfernandez/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/seelaff/index.html b/miembros/seelaff/index.html index c0325fd11..e4ad126a9 100644 --- a/miembros/seelaff/index.html +++ b/miembros/seelaff/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/selfprint/index.html b/miembros/selfprint/index.html index df83a3110..f922c2a8f 100644 --- a/miembros/selfprint/index.html +++ b/miembros/selfprint/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/skrullchull/index.html b/miembros/skrullchull/index.html index 4e53262f3..29e2d6991 100644 --- a/miembros/skrullchull/index.html +++ b/miembros/skrullchull/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/soneban/index.html b/miembros/soneban/index.html index 00825821e..aae662754 100644 --- a/miembros/soneban/index.html +++ b/miembros/soneban/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/ssebastianj/index.html b/miembros/ssebastianj/index.html index 5f754b0e5..6c7d0243c 100644 --- a/miembros/ssebastianj/index.html +++ b/miembros/ssebastianj/index.html @@ -39,7 +39,7 @@ GitHub h"> - + Ir al contenido principal @@ -73,12 +73,12 @@ - + diff --git a/miembros/ssergio/index.html b/miembros/ssergio/index.html index 8f0c432cb..bad829067 100644 --- a/miembros/ssergio/index.html +++ b/miembros/ssergio/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/sserrano44/index.html b/miembros/sserrano44/index.html index e59afaba0..6845d458e 100644 --- a/miembros/sserrano44/index.html +++ b/miembros/sserrano44/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/sysface/index.html b/miembros/sysface/index.html index 3591eb4a3..b210c3e63 100644 --- a/miembros/sysface/index.html +++ b/miembros/sysface/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/miembros/tapicer/index.html b/miembros/tapicer/index.html index 320a460a3..b8e9a115c 100644 --- a/miembros/tapicer/index.html +++ b/miembros/tapicer/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/teury/index.html b/miembros/teury/index.html index c051f46c9..a81c99c0d 100644 --- a/miembros/teury/index.html +++ b/miembros/teury/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/tin/index.html b/miembros/tin/index.html index d6869c423..6534d96ba 100644 --- a/miembros/tin/index.html +++ b/miembros/tin/index.html @@ -33,7 +33,7 @@ En twitter soy @tin_nqn_ En LinkedIn"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + diff --git a/miembros/tomyfer11/index.html b/miembros/tomyfer11/index.html index 89293f7a1..fc544f68c 100644 --- a/miembros/tomyfer11/index.html +++ b/miembros/tomyfer11/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/uxun/index.html b/miembros/uxun/index.html index 4405821db..2bdf1cc63 100644 --- a/miembros/uxun/index.html +++ b/miembros/uxun/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/victor/index.html b/miembros/victor/index.html index 7ab716411..773cd7bb8 100644 --- a/miembros/victor/index.html +++ b/miembros/victor/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/vonpixarg/index.html b/miembros/vonpixarg/index.html index bd7e3bfba..ea7e5ad4a 100644 --- a/miembros/vonpixarg/index.html +++ b/miembros/vonpixarg/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/walexnet/index.html b/miembros/walexnet/index.html index 7e3b2189d..6a5e262f2 100644 --- a/miembros/walexnet/index.html +++ b/miembros/walexnet/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/walteralini/index.html b/miembros/walteralini/index.html index b09d45c44..b6ecd8453 100644 --- a/miembros/walteralini/index.html +++ b/miembros/walteralini/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/miembros/werben/index.html b/miembros/werben/index.html index 20104571a..0edfe9b9a 100644 --- a/miembros/werben/index.html +++ b/miembros/werben/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/miembros/wolchesky/index.html b/miembros/wolchesky/index.html index d77d61841..2f0838886 100644 --- a/miembros/wolchesky/index.html +++ b/miembros/wolchesky/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembros/zontxo/index.html b/miembros/zontxo/index.html index ab782b25e..7e70375f1 100644 --- a/miembros/zontxo/index.html +++ b/miembros/zontxo/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miembrosdepyar/index.html b/miembrosdepyar/index.html index 7b2d5fabf..0401c9b4c 100644 --- a/miembrosdepyar/index.html +++ b/miembrosdepyar/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/miniejemplos/index.html b/miniejemplos/index.html index b8238a1c1..cb3bb7883 100644 --- a/miniejemplos/index.html +++ b/miniejemplos/index.html @@ -27,7 +27,7 @@ Hola mundo El"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + @@ -105,15 +105,15 @@

    Mini Ejemplos

    >>> [numero ** 3 for numero in range(1, 11)] [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] -->

    Generar una lista de los cubos de los números impares entre 1 y 10

    -
    >>> [numero ** 3 for numero in range(1, 11) if numero % 2 == 1]
    -[1, 27, 125, 343, 729]
    +
    >>> [numero ** 3 for numero in range(1, 11) if numero % 2 == 1]
    +[1, 27, 125, 343, 729]
     

    Funciones

    -
    >>> def hola(nombre):
    -...     print u"Hola, %s, ¿cómo estás?" % nombre
    -...
    ->>> hola('Mls')
    -Hola, Matías, ¿cómo estás?
    +
    >>> def hola(nombre):
    +...     print u"Hola, %s, ¿cómo estás?" % nombre
    +...
    +>>> hola('Mls')
    +Hola, Matías, ¿cómo estás?
     
    diff --git a/minifaq/index.html b/minifaq/index.html index ca9f23e69..39e0ba597 100644 --- a/minifaq/index.html +++ b/minifaq/index.html @@ -31,7 +31,7 @@ ¿Cuales son los interpretes que puedo usar? ¿Com"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/mudanzaservidoresdominio/index.html b/mudanzaservidoresdominio/index.html index 43d2cae03..97adb4e5e 100644 --- a/mudanzaservidoresdominio/index.html +++ b/mudanzaservidoresdominio/index.html @@ -30,7 +30,7 @@ tutorialpython.com.ar -> humitos python"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/nickar/index.html b/nickar/index.html index 8da982d3c..7074c36c5 100644 --- a/nickar/index.html +++ b/nickar/index.html @@ -26,7 +26,7 @@ TODO:Hablar sobre mi. Email: np AT SPAMFREE cs DOT uns DOT edu DOT ar"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/nicocesar/index.html b/nicocesar/index.html index a758a2056..39f31fcfe 100644 --- a/nicocesar/index.html +++ b/nicocesar/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/nicoechaniz/index.html b/nicoechaniz/index.html index b844bba5b..90465f00c 100644 --- a/nicoechaniz/index.html +++ b/nicoechaniz/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/nicolasdemarchi/index.html b/nicolasdemarchi/index.html index 981c31127..c9b748e86 100644 --- a/nicolasdemarchi/index.html +++ b/nicolasdemarchi/index.html @@ -26,7 +26,7 @@ Blog: http://gilgamezh.me/blog Actualmente vivo en CABA y trabajo en sistemas desde el Y2K. Sysadmin/WebOps/SRE/etc. Estudiante truncado de Sistemas. Me gusta mucho tra"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/noticias/index.html b/noticias/index.html index fac85f899..04b3126a5 100644 --- a/noticias/index.html +++ b/noticias/index.html @@ -34,7 +34,7 @@ Python Argentina participará con un '> - + Ir al contenido principal @@ -68,12 +68,12 @@ - + diff --git a/nubis/index.html b/nubis/index.html index 8c6411c66..d3558d056 100644 --- a/nubis/index.html +++ b/nubis/index.html @@ -26,7 +26,7 @@ Proyectos: http://woobiz.com.ar Email: gnubis AT gmail DOT com"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/nuevologo/index.html b/nuevologo/index.html index 6399b0d2c..a2a91c069 100644 --- a/nuevologo/index.html +++ b/nuevologo/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/nuevositio/index.html b/nuevositio/index.html index 553e2711a..476433473 100644 --- a/nuevositio/index.html +++ b/nuevositio/index.html @@ -37,7 +37,7 @@ http://www.imgs.com.ar/imgs/f/6/7/f6710b27328bca52c9b2e2b8da012eda8f298749."> - + Ir al contenido principal @@ -71,12 +71,12 @@ - + diff --git a/obteniendorespuestas/index.html b/obteniendorespuestas/index.html index 6d5bd0372..27e4c620c 100644 --- a/obteniendorespuestas/index.html +++ b/obteniendorespuestas/index.html @@ -27,7 +27,7 @@ Nota del Traductor En el texto se utiliza varias veces la abreviación "RTFM!", que traducida significa "lee el maldito manual!"(Read The Fucking Manual!'> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/omar-vega/index.html b/omar-vega/index.html index 2e131ab44..a2429b19a 100644 --- a/omar-vega/index.html +++ b/omar-vega/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/orms/index.html b/orms/index.html index b089e79e4..fafa57762 100644 --- a/orms/index.html +++ b/orms/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/osiris/index.html b/osiris/index.html index 30eb807b6..157e77fc3 100644 --- a/osiris/index.html +++ b/osiris/index.html @@ -26,7 +26,7 @@ Home: http://osiux.com BAL: http://wiki.buenosaireslibre.org/NodoOsiux"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/pabloalejandrocostesich/index.html b/pabloalejandrocostesich/index.html index 7405bb9e7..0106aa7f5 100644 --- a/pabloalejandrocostesich/index.html +++ b/pabloalejandrocostesich/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/pablopetenello/index.html b/pablopetenello/index.html index 9b98569c9..f0b927e3f 100644 --- a/pablopetenello/index.html +++ b/pablopetenello/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/pabloseminario/index.html b/pabloseminario/index.html index ab6efe030..703317989 100644 --- a/pabloseminario/index.html +++ b/pabloseminario/index.html @@ -31,7 +31,7 @@ Mail IDONTWANT pabluk AT CRIPPY gmail SPAM DOT com"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/pabloziliani/index.html b/pabloziliani/index.html index f45318fe5..cb62db5ba 100644 --- a/pabloziliani/index.html +++ b/pabloziliani/index.html @@ -27,7 +27,7 @@ Pablo Ziliani's Complete Waste of Time ||<tablewidth="" tablestyle=""> {{attachment:birdman.jpg}} || {{attachment:hormigas.jpg}} || {{attachment:sugus.jpg}} || {{attachment:honey.j"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/patriciomolina/index.html b/patriciomolina/index.html index aab9d3775..4537bcf9e 100644 --- a/patriciomolina/index.html +++ b/patriciomolina/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/pep/index.html b/pep/index.html index a4a745b6c..cea52fdbb 100644 --- a/pep/index.html +++ b/pep/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/planeta/index.html b/planeta/index.html index ce5da7ce0..39379963a 100644 --- a/planeta/index.html +++ b/planeta/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/plpython/index.html b/plpython/index.html index 8022a85b3..587229183 100644 --- a/plpython/index.html +++ b/plpython/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -93,84 +93,84 @@

    Pl/python: Python Dentro De Postgresql

    Nota: PostgreSQL 8.1 no soporta argumentos por nombre, recibir valores compuestos, devolver listas/tuplas o usar generadores.

    Ejemplo simple

    Calcular el valor máximo entre dos enteros, descartando valores nulos:

    -
    CREATE FUNCTION pymax (a integer, b integer)
    -  RETURNS integer
    -AS $$
    -  if (a is None) or (b is None):
    -    return None
    -  if a > b:
    -    return a
    -  return b
    -$$ LANGUAGE plpythonu;
    -
    --- invoco la función:
    -SELECT pymax(2, 3);
    --- devuelve 3
    +
    CREATE FUNCTION pymax (a integer, b integer)
    +  RETURNS integer
    +AS $$
    +  if (a is None) or (b is None):
    +    return None
    +  if a > b:
    +    return a
    +  return b
    +$$ LANGUAGE plpythonu;
    +
    +-- invoco la función:
    +SELECT pymax(2, 3);
    +-- devuelve 3
     

    Recibir tipos compuestos

    Las funciones plpython pueden recibir tipos compuestos (ej.registros de tablas) como diccionarios:

    -
    CREATE TABLE empleado (
    -  nombre TEXT,
    -  salario INTEGER,
    -  edad INTEGER
    -);
    -
    -CREATE FUNCTION sueldo_alto (e empleado)
    -  RETURNS boolean
    -AS $$
    -  if e["salario"] > 200000:
    -    return True
    -  if (e["edad"] < 30) and (e["salario"] > 100000):
    -    return True
    -  return False
    -$$ LANGUAGE plpythonu;
    +
    CREATE TABLE empleado (
    +  nombre TEXT,
    +  salario INTEGER,
    +  edad INTEGER
    +);
    +
    +CREATE FUNCTION sueldo_alto (e empleado)
    +  RETURNS boolean
    +AS $$
    +  if e["salario"] > 200000:
    +    return True
    +  if (e["edad"] < 30) and (e["salario"] > 100000):
    +    return True
    +  return False
    +$$ LANGUAGE plpythonu;
     

    Devolver tipos compuestos

    Los tipos compuestos pueden ser devueltos como secuencias (tuplas o listas), diccionarios u objetos. En este ejemplo se devuelve un tipo compuesto representando una persona:

    -
    CREATE TYPE persona AS (
    -  nombre   TEXT,
    -  apellido TEXT
    -);
    -
    -CREATE FUNCTION crear_persona (nombre TEXT, apellido TEXT)
    -  RETURNS persona
    -AS $$
    -  return [ nombre, apellido ]
    -  # o como tupla: return ( nombre, apellido )
    -  # o como diccionario: return { "nombre": nombre, "apellido": apellido }
    -$$ LANGUAGE plpythonu;
    -
    -CREATE FUNCTION crear_persona (nombre TEXT, persona TEXT)
    -  RETURNS persona
    -AS $$
    -  class Persona:
    -    def __init__ (self, n, a):
    -      self.nombre = n
    -      self.apellido = a
    -  return Persona(nombre, apellido)
    -$$ LANGUAGE plpythonu;
    +
    CREATE TYPE persona AS (
    +  nombre   TEXT,
    +  apellido TEXT
    +);
    +
    +CREATE FUNCTION crear_persona (nombre TEXT, apellido TEXT)
    +  RETURNS persona
    +AS $$
    +  return [ nombre, apellido ]
    +  # o como tupla: return ( nombre, apellido )
    +  # o como diccionario: return { "nombre": nombre, "apellido": apellido }
    +$$ LANGUAGE plpythonu;
    +
    +CREATE FUNCTION crear_persona (nombre TEXT, persona TEXT)
    +  RETURNS persona
    +AS $$
    +  class Persona:
    +    def __init__ (self, n, a):
    +      self.nombre = n
    +      self.apellido = a
    +  return Persona(nombre, apellido)
    +$$ LANGUAGE plpythonu;
     

    Devolver múltiples tipos escalares o compuestos (''set-of'')

    Se puede devolver múltiples valores (usando listas/tuplas, iteradores o generadores). En este ejemplo se devuelven varios saludos:

    -
    CREATE TYPE saludo AS (
    -  mensaje TEXT, -- hola
    -  a_quien TEXT  -- mundo
    -);
    -
    -CREATE FUNCTION saludar (mensaje TEXT)
    -  RETURNS SETOF saludo
    -AS $$
    -  # devolver una tupla conteniendo lista de tipos compuestos
    -  # todas las otras combinaciones son posibles
    -  return ( [ mensaje, "Mundo" ], [ mensaje, "PostgreSQL" ], [ mensaje, "PL/Python" ] )
    -$$ LANGUAGE plpythonu;
    -
    -CREATE FUNCTION saludar_generador (mensaje TEXT)
    -  RETURNS SETOF saludo
    -AS $$
    -  for a_quien in [ "Mundo", "PostgreSQL", "PL/Python" ]:
    -    yield ( mensaje, a_quien )
    -$$ LANGUAGE plpythonu;
    +
    CREATE TYPE saludo AS (
    +  mensaje TEXT, -- hola
    +  a_quien TEXT  -- mundo
    +);
    +
    +CREATE FUNCTION saludar (mensaje TEXT)
    +  RETURNS SETOF saludo
    +AS $$
    +  # devolver una tupla conteniendo lista de tipos compuestos
    +  # todas las otras combinaciones son posibles
    +  return ( [ mensaje, "Mundo" ], [ mensaje, "PostgreSQL" ], [ mensaje, "PL/Python" ] )
    +$$ LANGUAGE plpythonu;
    +
    +CREATE FUNCTION saludar_generador (mensaje TEXT)
    +  RETURNS SETOF saludo
    +AS $$
    +  for a_quien in [ "Mundo", "PostgreSQL", "PL/Python" ]:
    +    yield ( mensaje, a_quien )
    +$$ LANGUAGE plpythonu;
     

    Disparadores (Triggers)

    Cuando una función plpython es usada en un disparador, el diccionario TD contiene:

    @@ -197,28 +197,28 @@

    Pl/python: Python Dentro De Postgresql

    Adicionalmente, el módulo plpy provee dos funciones: execute y prepare.

    Llamar a plpy.execute(query, limit) con una consulta (query: string) y un límite de registros opcional (limit), permite ejecutar la consulta y devuelve los resultados en un objeto que emula una lista de diccionarios, pudiendo acceder por número de fila y nombre de columna. Tiene tres métodos adicionales: nrows que devuelve el número de filas, y status.

    Ejemplo:

    -
    rv = plpy.execute("SELECT * FROM mi_tabla", 5)
    -for fila in rv:
    -   print fila['columna']
    +
    rv = plpy.execute("SELECT * FROM mi_tabla", 5)
    +for fila in rv:
    +   print fila['columna']
     

    La función plpy.prepare(query,[parameter_types]), prepara el plan de ejecución para una consulta, se le pasa la consulta como string y la lista de tipos de parámetros:

    -
    plan = plpy.prepare("SELECT apellido FROM usuario WHERE nombre = $1 AND casado = $2 ", [ "text", "boolean" ])
    +
    plan = plpy.prepare("SELECT apellido FROM usuario WHERE nombre = $1 AND casado = $2 ", [ "text", "boolean" ])
     

    text y boolean son los tipos de la variables que se pasara como parámetros ($1 y $2).

    Despues de preparar la sentencia, usar la función plpy.execute para ejecutarla:

    -
    rv = plpy.execute(plan, [ "Mariano", True ], 5)
    +
    rv = plpy.execute(plan, [ "Mariano", True ], 5)
     

    Se pasa el plan como primer argumento, los parámetros como segundo (en este caso, busca nombre="Mariano" y si esta casado). El límite (tercer argumento) es opcional.

    Al preparar un plan, este se almacena para usarlo posteriormente. Para usarlo eficazmente entre llamada y llamada, se debe usar un diccionario de almacenamiento persistente (SD o GD) para guardarlo:

    -
    CREATE FUNCTION usar_plan_guardado() RETURNS trigger AS $$
    -    if SD.has_key("plan"):
    -        plan = SD["plan"] # está el plan, lo reutilizo
    -    else:
    -        # no esta el plan, lo creo y almaceno en el diccionario persistente
    -        plan = plpy.prepare("SELECT 1")
    -        SD["plan"] = plan
    -    # continua la función...
    -$$ LANGUAGE plpythonu;
    +
    CREATE FUNCTION usar_plan_guardado() RETURNS trigger AS $$
    +    if SD.has_key("plan"):
    +        plan = SD["plan"] # está el plan, lo reutilizo
    +    else:
    +        # no esta el plan, lo creo y almaceno en el diccionario persistente
    +        plan = plpy.prepare("SELECT 1")
    +        SD["plan"] = plan
    +    # continua la función...
    +$$ LANGUAGE plpythonu;
     
    diff --git a/preferenciasdelusuario/index.html b/preferenciasdelusuario/index.html index e6946c1fb..0c8f42d9f 100644 --- a/preferenciasdelusuario/index.html +++ b/preferenciasdelusuario/index.html @@ -27,7 +27,7 @@ Si sigue el enlace de `[[GetText(Create Profile)]]`_, se le c"> - +Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/preguntasfrecuentes/index.html b/preguntasfrecuentes/index.html index 08cacc8ee..68735c274 100644 --- a/preguntasfrecuentes/index.html +++ b/preguntasfrecuentes/index.html @@ -34,7 +34,7 @@ ¿Cómo participar? ¿Cómo se or"> - +Ir al contenido principal @@ -68,12 +68,12 @@ - + @@ -218,47 +218,47 @@

    Preguntasfrecuentes

    Las celdas son como cajones donde se guarda una variable para que pueda ser manipulada dentro de generadores, funciones y clases internos (closures).

    Técnicamente hablando, las funciones internas, clases, expresiones generadoras y demás pueden tener "variables libres" (ver ejemplos). Esas variables libres son las celdas, y se rellenan con un valor como cualquier variable - el chiste es que varios pedazos de código pueden apuntar a la misma celda (y por lo tanto modificar la misma variable).

    Ejemplo:

    -
    def f(x):
    -   def g():
    -      return x + 1
    -   return g()
    -   # aquí "x" se incrementó, x no es local a 'g'
    -   # x es una celda en toda la función f
    -   # para que pueda ser accedida desde g y f a la vez
    +
    def f(x):
    +   def g():
    +      return x + 1
    +   return g()
    +   # aquí "x" se incrementó, x no es local a 'g'
    +   # x es una celda en toda la función f
    +   # para que pueda ser accedida desde g y f a la vez
     

    Otro

    -
    def f(l):
    -   escala = sum(l)
    -   return set( x / escala for x in l )
    -   # escala es una celda porque "x / escala for x in l"
    -   # es una expresión generadora, y su única forma de
    -   # acceder a "escala" es a través de la celda
    +
    def f(l):
    +   escala = sum(l)
    +   return set( x / escala for x in l )
    +   # escala es una celda porque "x / escala for x in l"
    +   # es una expresión generadora, y su única forma de
    +   # acceder a "escala" es a través de la celda
     

    Es importante saber cuáles de nuestras variables son celdas y cuáles simplemente locales, porque la sintaxis de Python nos prohíbe borrar celdas, no así variables locales:

    -
    def f(x):
    -   rv = set( [ i*x for i in xrange(10) ] )
    -   del x # bizarro pero ok
    -   return rv
    -
    -def g(x):
    -   rv = set( i*x for i in xrange(10) )
    -   del x # error de sintaxis, no se pueden borrar celdas
    -   return rv
    +
    def f(x):
    +   rv = set( [ i*x for i in xrange(10) ] )
    +   del x # bizarro pero ok
    +   return rv
    +
    +def g(x):
    +   rv = set( i*x for i in xrange(10) )
    +   del x # error de sintaxis, no se pueden borrar celdas
    +   return rv
     

    Nótese que en f, x no es una celda porque ocurre en una expresión de lista por comprensión - que se parece, pero no es un generador.

    ¿Qué son los ''fastlocals''?

    La documentación de Python sólo menciona un scope lógico local, el "local". Tiene sentido, puesto que las variables son o locales, o globales, o celdas (ver pregunta anterior).

    Las variables locales todos las conocemos:

    -
    def f():
    -   x = 4 # x es local
    +
    def f():
    +   x = 4 # x es local
     

    Los parámetros de una función también son variables locales. Por ende, self, en una función de una instancia, es también una variable local.

    Las variables globales todos las conocemos también:

    -
    llamadas = 0
    -
    -def f():
    -   global llamadas # llamadas es global
    -   llamadas += 1
    +
    llamadas = 0
    +
    +def f():
    +   global llamadas # llamadas es global
    +   llamadas += 1
     

    Las variables globales son "locales al módulo". Dentro de otro módulo, habrá otras globales.

    Las "más globales de las globales" serían las variables globales del módulo "builtin`*"*, puesto que cuando un nombre no se encuentra ni entre las locales ni entre las globales del módulo, se busca en el módulo :underline:`builtin.

    @@ -270,26 +270,26 @@

    Preguntasfrecuentes

    Esas son "fastlocals".

    Casi todas las variables locales que se declaren van a ser rápidas. La única forma que conozco de generar variables locales lentas es con import * (en el scope local de una función, lo que es muy poco común), o especificando un diccionario de locales con eval()

    La forma de "declarar" una variable de este tipo es simplemente asignandole un valor:

    -
    def f(...):
    -   ...
    -   x = 5
    -   ...
    +
    def f(...):
    +   ...
    +   x = 5
    +   ...
     

    Esto ya define a "x" como variable local rápida. Y ojo, tiene ese status en todo el bloque.

    O sea que cosas como esta no van a funcionar:

    -
    def f():
    -   if x != 3:
    -     ...
    -   ...
    -   x = 5
    +
    def f():
    +   if x != 3:
    +     ...
    +   ...
    +   x = 5
     

    ¿Por qué no? Porque x es local incluso cuando se accede en 'x != 3', y a esa altura, nunca fue asignada. Muchos pensarían que python va a ir a buscar una variable global llamada 'x' - nop... no es así. La simple asignación a x la define implícitamente como variable local y no global. Si queremos que sea global (y que la asignación cambie el valor de la variable global), hay que hacer:

    -
    def f():
    -   global x
    -   if x != 3:
    -     ...
    -   ...
    -   x = 5
    +
    def f():
    +   global x
    +   if x != 3:
    +     ...
    +   ...
    +   x = 5
     

    Sobre Python (el intérprete)

    ¿Cuáles son los intérpretes que puedo usar?

    @@ -383,7 +383,7 @@

    Preguntasfrecuentes

    ¿Hay alguna forma de saber la ruta (path) del archivo actual?

    MarianoGuerra preguntó esto en este hilo: http://mx.grulic.org.ar/lurker/thread/20080719.055432.4df0ac40.es.html Esencialmente, el problema es saber la ruta absoluta del script python que se está ejecutando

    La respuesta que le dio MartinBothiry es hacer:

    -
    os.path.abspath(os.path.dirname(__file__))
    +
    os.path.abspath(os.path.dirname(__file__))
     

    ¿Uso el modulo array o listas?

    SebastianBassi preguntó en este hilo: http://mx.grulic.org.ar/lurker/thread/20090803.144308.0aabeb1b.en.html

    @@ -403,16 +403,16 @@

    Preguntasfrecuentes

    A veces el "is" me dice una cosa y otras otra, ¿funciona mal?

    "is" no falla, compara si dos objetos son el mismo (no si son iguales).

    En algunos casos, ofrece resultado que a primera vista sorprenden...

    -
    >>> a = 3
    ->>> b = 3
    ->>> a is b
    -True
    +
    >>> a = 3
    +>>> b = 3
    +>>> a is b
    +True
     

    En este caso a apunta a un 3 en memoria, y b apunta al mismo 3 en memoria. Python no creó dos objetos "3", sino que usó el mismo para los nombres a y b.

    -
    >>> a = 500
    ->>> b = 500
    ->>> a is b
    -False
    +
    >>> a = 500
    +>>> b = 500
    +>>> a is b
    +False
     

    Aquí a apunta a un 500 en memoria, y b apunta a otro 500 en memoria. Python sí creó dos objetos "500".

    La pregunta es... ¿por qué la diferencia de comportamiento? Python (ojo, ver abajo) precachea (o tiene internalizado) algunos enteros chicos, porque sabe que siempre se van a usar.

    diff --git a/preguntassinrespuesta/index.html b/preguntassinrespuesta/index.html index 461e9f1fc..e7dcfd810 100644 --- a/preguntassinrespuesta/index.html +++ b/preguntassinrespuesta/index.html @@ -27,7 +27,7 @@ Frameworks web: django vs turbogears vs zope vs plone vs pylons ORMS: comp"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - +
    diff --git a/primerproyecto/index.html b/primerproyecto/index.html index b663d520e..c923d8e59 100644 --- a/primerproyecto/index.html +++ b/primerproyecto/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    diff --git a/proximareunion/index.html b/proximareunion/index.html index eef8568d6..e9b7bb7d8 100644 --- a/proximareunion/index.html +++ b/proximareunion/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    diff --git a/proyecto/index.html b/proyecto/index.html index d85d9e429..50b369ce5 100644 --- a/proyecto/index.html +++ b/proyecto/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    diff --git a/proyectos/index.html b/proyectos/index.html index 899f9cdb6..7a522659b 100644 --- a/proyectos/index.html +++ b/proyectos/index.html @@ -28,7 +28,7 @@ Administrador de colas de mensajes, con soporte para múltiples protocolos: SMTP (mail), SMPP (S"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    diff --git a/prueba/index.html b/prueba/index.html index af3736854..b4116b9fc 100644 --- a/prueba/index.html +++ b/prueba/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/pruebaloca/index.html b/pruebaloca/index.html index 9bcfb1ab7..9aa075d10 100644 --- a/pruebaloca/index.html +++ b/pruebaloca/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/pruebamail/index.html b/pruebamail/index.html index d0f2bbb79..a150f917b 100644 --- a/pruebamail/index.html +++ b/pruebamail/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/pruebavideo/index.html b/pruebavideo/index.html index 2a2a983a6..7cd45d1e1 100644 --- a/pruebavideo/index.html +++ b/pruebavideo/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/py2exe/index.html b/py2exe/index.html index d0be942b6..85ec6faf2 100644 --- a/py2exe/index.html +++ b/py2exe/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/pyar/index.html b/pyar/index.html index 918ed3a44..cce46b258 100644 --- a/pyar/index.html +++ b/pyar/index.html @@ -28,7 +28,7 @@ ¿Qué ha"> - +Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/pycamp/index.html b/pycamp/index.html index 5267b5624..1d212a5b9 100644 --- a/pycamp/index.html +++ b/pycamp/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/pycamp2009resultados/index.html b/pycamp2009resultados/index.html index be5981d8f..55d557f0a 100644 --- a/pycamp2009resultados/index.html +++ b/pycamp2009resultados/index.html @@ -28,7 +28,7 @@ La idea es que todos los que participaron agreguen a"> - +Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/pycamporm/index.html b/pycamporm/index.html index 0ca6a3ba9..9d33a69aa 100644 --- a/pycamporm/index.html +++ b/pycamporm/index.html @@ -31,7 +31,7 @@ SqlAlchemy es un excelente orm cual nos permite trabajar con bases de datos relacionales sin tener que escribir sql, y pycamp.orm es una "> - +Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/pycon/index.html b/pycon/index.html index a29bec582..2a0ffb4b5 100644 --- a/pycon/index.html +++ b/pycon/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/pyconapp/index.html b/pyconapp/index.html index 0638cb285..02228d771 100644 --- a/pyconapp/index.html +++ b/pyconapp/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/pyconar2015/index.html b/pyconar2015/index.html index 0c1c9d1a8..66af5b14e 100644 --- a/pyconar2015/index.html +++ b/pyconar2015/index.html @@ -27,7 +27,7 @@ ¿Por qué PyConAr en Mendoza? Crear una comunidad de Python activa en Mendoza significa sumar más y más miembros interesados en esta tecnología, y para ello necesitamos encarar una estrategia "> - +Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/pyconarvotacioncharlas/index.html b/pyconarvotacioncharlas/index.html index 4f7cd54dd..15ce6d0dc 100644 --- a/pyconarvotacioncharlas/index.html +++ b/pyconarvotacioncharlas/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/pyday/index.html b/pyday/index.html index 6acb198db..d29feb3d5 100644 --- a/pyday/index.html +++ b/pyday/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/pyday2/index.html b/pyday2/index.html index d496868af..c48745c38 100644 --- a/pyday2/index.html +++ b/pyday2/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/pydayjunin2015/index.html b/pydayjunin2015/index.html index e33b49101..4a4897d14 100644 --- a/pydayjunin2015/index.html +++ b/pydayjunin2015/index.html @@ -31,7 +31,7 @@ Roberto Alsi"> - +Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/python-ya/index.html b/python-ya/index.html index 22447acd2..06001ae9b 100644 --- a/python-ya/index.html +++ b/python-ya/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/python3mil/index.html b/python3mil/index.html index 6b44a23d9..df0c6c8e0 100644 --- a/python3mil/index.html +++ b/python3mil/index.html @@ -26,7 +26,7 @@ ¿Python 3.0 no es compatible hacia atras con versiones pre"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/pythoneneldiaadia/index.html b/pythoneneldiaadia/index.html index 1d3d40d8c..e64194c96 100644 --- a/pythoneneldiaadia/index.html +++ b/pythoneneldiaadia/index.html @@ -26,7 +26,7 @@ Programas escri"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/pythonzen/index.html b/pythonzen/index.html index 16897e9d1..9f4406bfc 100644 --- a/pythonzen/index.html +++ b/pythonzen/index.html @@ -33,7 +33,7 @@ Plano es mejor que anidado. Espaciado"> - +Ir al contenido principal @@ -67,12 +67,12 @@ - + @@ -92,7 +92,7 @@

    El Zen De Python

    Nuestros principios guía 🙂

    -
    import this
    +
    import this
     
    1. Lindo es mejor que feo.

    2. diff --git a/pyweek/index.html b/pyweek/index.html index 0f01178d9..98febed6f 100644 --- a/pyweek/index.html +++ b/pyweek/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    diff --git a/quienessomos/index.html b/quienessomos/index.html index 906fe6f20..9687ac998 100644 --- a/quienessomos/index.html +++ b/quienessomos/index.html @@ -27,7 +27,7 @@ ¿Qué hacemos? Organizamo"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - +
    diff --git a/ramiroalgozino/index.html b/ramiroalgozino/index.html index 2079ea389..1f7877a7c 100644 --- a/ramiroalgozino/index.html +++ b/ramiroalgozino/index.html @@ -28,7 +28,7 @@ Launchpad: https://launchpad.net/~algozino GoogleCode: http://code.google.com/u/a"> - +Ir al contenido principal @@ -62,12 +62,12 @@ - + diff --git a/ramiromorales/index.html b/ramiromorales/index.html index 3f6e40121..16802c4ff 100644 --- a/ramiromorales/index.html +++ b/ramiromorales/index.html @@ -29,7 +29,7 @@ Miembro de PyAr desde el 2006. Obsesión actual (desde el 2006 bah"> - +Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/readwritegroup/index.html b/readwritegroup/index.html index 131400e3d..bb4b56e20 100644 --- a/readwritegroup/index.html +++ b/readwritegroup/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/recetario/alarmaprecaria/index.html b/recetario/alarmaprecaria/index.html index 298f109b4..fced3d037 100644 --- a/recetario/alarmaprecaria/index.html +++ b/recetario/alarmaprecaria/index.html @@ -33,7 +33,7 @@ hour = dt[3] "> - +Ir al contenido principal @@ -67,12 +67,12 @@ - + @@ -92,76 +92,76 @@

    Alarma Precaria

    Alarma mínima y básica de línea de comandos.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -import time
    -import os
    -not_executed = 1
    -while(not_executed):
    -    dt = list(time.localtime())
    -    hour = dt[3]
    -    minute = dt[4]
    -    sleep(1)
    -    if hour == 8 and minute == 30: # modificar hour y minute a la hora deseada
    -        os.system("xdg-open /home/user/ring.ogg") # RingTone (?)
    -        not_executed = 0
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +import time
    +import os
    +not_executed = 1
    +while(not_executed):
    +    dt = list(time.localtime())
    +    hour = dt[3]
    +    minute = dt[4]
    +    sleep(1)
    +    if hour == 8 and minute == 30: # modificar hour y minute a la hora deseada
    +        os.system("xdg-open /home/user/ring.ogg") # RingTone (?)
    +        not_executed = 0
     

    Comentarios

    Facundo

    Hay un par de cambios triviales para hacerle: se puede reemplazar el not_executed por un break, no hace falta declarar el encoding, y usar localtime() como corresponde..

    -
    #!/usr/bin/env python
    -
    -import time
    -import os
    -while(True):
    -    dt = time.localtime()
    -    sleep(1)
    -    if dt.tm_hour == 8 and dt.tm_min == 30: # modificar hour y minute a la hora deseada
    -        os.system("xdg-open /home/user/ring.ogg") # RingTone (?)
    -        break
    +
    #!/usr/bin/env python
    +
    +import time
    +import os
    +while(True):
    +    dt = time.localtime()
    +    sleep(1)
    +    if dt.tm_hour == 8 and dt.tm_min == 30: # modificar hour y minute a la hora deseada
    +        os.system("xdg-open /home/user/ring.ogg") # RingTone (?)
    +        break
     

    ... pero realmente está mal planteado la resolución: no hay que usar un while ahí:

    -
    import time
    -import os
    -
    -# modificar hour y minute a la hora deseada
    -HOUR = 8
    -MIN = 30
    -
    -t = time.localtime()
    -nowhms = t.tm_hour * 3600 + t.tm_min * 60 + t.tm_sec
    -alarm = HOUR * 3600 + MIN * 60
    -delta = alarm - nowhms
    -if delta < 0:
    -    # tomorrow
    -    delta += 3600 * 24
    -time.sleep(delta)
    -os.system("xdg-open /home/user/ring.ogg") # RingTone (?)
    +
    import time
    +import os
    +
    +# modificar hour y minute a la hora deseada
    +HOUR = 8
    +MIN = 30
    +
    +t = time.localtime()
    +nowhms = t.tm_hour * 3600 + t.tm_min * 60 + t.tm_sec
    +alarm = HOUR * 3600 + MIN * 60
    +delta = alarm - nowhms
    +if delta < 0:
    +    # tomorrow
    +    delta += 3600 * 24
    +time.sleep(delta)
    +os.system("xdg-open /home/user/ring.ogg") # RingTone (?)
     

    DanielMoisset

    Yo prefiero no sacar cuentas de fecha a mano, y en vez que datetime haga el trabajo sucio. Sobre todo porque maneja mejor casos delicados (que pasa si pongo la alarma justo antes de un cambio a horario de verano?) sin tener que pensarlos

    -
    import time, datetime
    -import os
    -
    -# modificar hour y minute a la hora deseada
    -
    -HOUR = 8
    -MIN = 30
    -
    -now = datetime.datetime.now()
    -alarm = now.replace(hour=HOUR, minute=MIN)
    -if alarm < now:
    -    # Set the alarm tomorrow
    -    alarm += datetime.timedelta(days=1)
    -time.sleep((alarm-now).seconds)
    -os.system("xdg-open /home/user/ring.ogg") # RingTone (?)
    +
    import time, datetime
    +import os
    +
    +# modificar hour y minute a la hora deseada
    +
    +HOUR = 8
    +MIN = 30
    +
    +now = datetime.datetime.now()
    +alarm = now.replace(hour=HOUR, minute=MIN)
    +if alarm < now:
    +    # Set the alarm tomorrow
    +    alarm += datetime.timedelta(days=1)
    +time.sleep((alarm-now).seconds)
    +os.system("xdg-open /home/user/ring.ogg") # RingTone (?)
     

    Juancarlospaco

    Por lo menos en Linux se necesita el Shebang y declarar encoding, por que sino al usar "Vídeo-de-Música.ogv" de Ringtone traen problemas los acentos.


    A esta altura creo que es más importante agregar el correcto coloreado de sintaxis y cuidar la ortografía, a discutir si poner o no el encoding y el shebang. La idea es que las recetas sean genéricas, con ese encoding y ese shebang, no cubris todos los casos. Pej, copias y pegas, y tu editor guarda en latin1??

    Si funciona con:

    -
    usuario@maquina: ~$ python receta.py
    +
    usuario@maquina: ~$ python receta.py
     

    Es más que suficiente. -- JoaquinSorianello 2010-11-08T10:56:40-0300

    diff --git a/recetario/aletras/index.html b/recetario/aletras/index.html index 75c22a93d..2bf297163 100644 --- a/recetario/aletras/index.html +++ b/recetario/aletras/index.html @@ -26,7 +26,7 @@ aLetras(numero) es una función a la que se le pasa un valor númerico y regresa un string con el valor numérico convertido a letras. Los valores que pueden ser convertidos pertenecen al ran"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -89,120 +89,120 @@

    Aletras

    Los valores que pueden ser convertidos pertenecen al rango -999.999.999,99 : 999.999.999,99. Si se proporciona una cadena fuera de rango, retorna el string "0".

    Siempre se trabaja con 2 decimales (se redondean los valores suministrados)

    Ejemplos:

    -
    >>> aLetras(1234.56)
    -' MIL DOSCIENTOS TREINTA Y CUATRO CON CINCUENTA Y SEIS CENTAVOS'
    ->>> aLetras(-240.99)
    -'MENOS DOSCIENTOS CUARENTA CON NOVENTA Y NUEVE CENTAVOS'
    ->>> aLetras(100)
    -'CIEN'
    ->>> aLetras(401201501.01)
    -'CUATROCIENTOS UN MILLON DOSCIENTOS UN MIL QUINIENTOS UNO CON UN CENTAVOS'
    ->>> aLetras(-0.76)
    -'MENOS CERO CON SETENTA Y SEIS CENTAVOS'
    ->>> aLetras(1000000000)
    -'0'
    +
    >>> aLetras(1234.56)
    +' MIL DOSCIENTOS TREINTA Y CUATRO CON CINCUENTA Y SEIS CENTAVOS'
    +>>> aLetras(-240.99)
    +'MENOS DOSCIENTOS CUARENTA CON NOVENTA Y NUEVE CENTAVOS'
    +>>> aLetras(100)
    +'CIEN'
    +>>> aLetras(401201501.01)
    +'CUATROCIENTOS UN MILLON DOSCIENTOS UN MIL QUINIENTOS UNO CON UN CENTAVOS'
    +>>> aLetras(-0.76)
    +'MENOS CERO CON SETENTA Y SEIS CENTAVOS'
    +>>> aLetras(1000000000)
    +'0'
     

    Observaciones

    La asignación y condicional en una línea -> numeros[1] = "UNO" if i == 2 else "UN" <- da problemas de sintaxis con versiones anteriores a Python 2.5.x

    Puede reemplazarse con:

    -
    if i == 2:
    -  numeros[1] = "UNO"
    -else:
    -  numeros[1] = "UN"
    +
    if i == 2:
    +  numeros[1] = "UNO"
    +else:
    +  numeros[1] = "UN"
     

    Código:

    -
    #fuente: Recetario de PyAR, http://python.com.ar/moin/Recetario
    -#autor: Cesar E Portela
    -#date: 06-05-2008
    -#version: 2
    -#para Python: 2.5.x
    -
    -def aLetras(numero):
    -
    -    numeros = {0:"CERO",2:"DOS",3:"TRES",4:"CUATRO",5:"CINCO",6:"SEIS",7:"SIETE",8:"OCHO",9:"NUEVE",
    -                10:"DIEZ",11:"ONCE",12:"DOCE",13:"TRECE",14:"CATORCE",15:"QUINCE",16:"DIECISEIS",17:"DIECISIETE",
    -                18:"DIECIOCHO",19:"DIECINUEVE",20:"VEINTE",30:"TREINTA",
    -                40:"CUARENTA",50:"CINCUENTA",60:"SESENTA",70:"SETENTA",80:"OCHENTA",90:"NOVENTA",100:"CIEN",
    -                500:"QUINIENTOS ",700:"SETECIENTOS ",900:"NOVECIENTOS "}
    -
    -    if abs(numero) > 999999999.99 : #mil millones, esta funcion procesa el rango [-999.999.999,99; 999.999.999,99]
    -        return ("0", 0)
    -    elif numero < 0:
    -        cadena = "MENOS "
    -    else:
    -        cadena = ""
    -
    -    #separo el numero entregado entre parte entera y sus decimales (tomando solo 2 y redondeando para arriba)
    -    entero = int(abs(numero))
    -    decimales = int((round(abs(numero), 2) + 0.001) * 100) % 100
    -
    -    #la parte entera es separada en grupos de tres digitos
    -    grupo1 = int(entero / 1000000)
    -    grupo2 = int((int(entero) - int(grupo1)*1000000)/1000)
    -    grupo3 = int(entero % 1000)
    -
    -    lista = [grupo1, grupo2, grupo3, decimales]
    -
    -    if (grupo1 + grupo2 + grupo3) == 0:
    -        cadena += numeros[0]
    -
    -    for i in xrange(4):
    -        unidad = lista[i] % 10
    -        decena = lista[i] % 100
    -        centena = (lista[i] / 100) % 10
    -        subcadena = ""
    -
    -        numeros[1] = "UNO" if i == 2 else "UN"
    -
    -        if i == 0: #grupo 1: el de los millones
    -            if decena == 1:
    -                subcadena = " MILLON "
    -            elif lista[i] > 1:
    -                subcadena = " MILLONES "
    -            else: #aqui se entra si lista[i] == 0 y en ese caso, no hay nada que procesar
    -                continue #se sigue con la siguiente iteracion del bucle
    -
    -        elif i == 1: #grupo2: el de los miles
    -            if lista[i] == 1:
    -                cadena += " MIL "
    -                continue #se pasa a la siguiente iteracion
    -            elif lista[i] > 1:
    -                subcadena = " MIL "
    -            else: #aqui se entra si lista[i] == 0 y en ese caso, no hay nada que procesar
    -                continue #se sigue con la siguiente iteracion del bucle
    -
    -        elif i == 3 and lista[i] != 0: #grupo4: el de los centavos (decimales)
    -            cadena += " CON "
    -            subcadena = " CENTAVOS"
    -
    -        if centena != 0:
    -            if centena == 1 and (unidad + decena) == 0:
    -                cadena += numeros[100]
    -                continue
    -            elif centena == 1:
    -                cadena += "CIENTO "
    -            elif centena == 5:
    -                cadena += numeros[500]
    -            elif centena == 7:
    -                cadena += numeros[700]
    -            elif centena == 9:
    -                cadena += numeros[900]
    -            else:
    -                cadena += numeros[centena] + "CIENTOS "
    -
    -        if decena != 0:
    -            if decena < 21:
    -                cadena += numeros[decena]
    -            elif decena < 30:
    -                cadena += "VENTI"+numeros[unidad]
    -            else:
    -                cadena += numeros[(decena/10)*10]
    -                if unidad > 0:
    -                    cadena += " Y "+numeros[unidad]
    -
    -        cadena += subcadena
    -
    -    return cadena
    +
    #fuente: Recetario de PyAR, http://python.com.ar/moin/Recetario
    +#autor: Cesar E Portela
    +#date: 06-05-2008
    +#version: 2
    +#para Python: 2.5.x
    +
    +def aLetras(numero):
    +
    +    numeros = {0:"CERO",2:"DOS",3:"TRES",4:"CUATRO",5:"CINCO",6:"SEIS",7:"SIETE",8:"OCHO",9:"NUEVE",
    +                10:"DIEZ",11:"ONCE",12:"DOCE",13:"TRECE",14:"CATORCE",15:"QUINCE",16:"DIECISEIS",17:"DIECISIETE",
    +                18:"DIECIOCHO",19:"DIECINUEVE",20:"VEINTE",30:"TREINTA",
    +                40:"CUARENTA",50:"CINCUENTA",60:"SESENTA",70:"SETENTA",80:"OCHENTA",90:"NOVENTA",100:"CIEN",
    +                500:"QUINIENTOS ",700:"SETECIENTOS ",900:"NOVECIENTOS "}
    +
    +    if abs(numero) > 999999999.99 : #mil millones, esta funcion procesa el rango [-999.999.999,99; 999.999.999,99]
    +        return ("0", 0)
    +    elif numero < 0:
    +        cadena = "MENOS "
    +    else:
    +        cadena = ""
    +
    +    #separo el numero entregado entre parte entera y sus decimales (tomando solo 2 y redondeando para arriba)
    +    entero = int(abs(numero))
    +    decimales = int((round(abs(numero), 2) + 0.001) * 100) % 100
    +
    +    #la parte entera es separada en grupos de tres digitos
    +    grupo1 = int(entero / 1000000)
    +    grupo2 = int((int(entero) - int(grupo1)*1000000)/1000)
    +    grupo3 = int(entero % 1000)
    +
    +    lista = [grupo1, grupo2, grupo3, decimales]
    +
    +    if (grupo1 + grupo2 + grupo3) == 0:
    +        cadena += numeros[0]
    +
    +    for i in xrange(4):
    +        unidad = lista[i] % 10
    +        decena = lista[i] % 100
    +        centena = (lista[i] / 100) % 10
    +        subcadena = ""
    +
    +        numeros[1] = "UNO" if i == 2 else "UN"
    +
    +        if i == 0: #grupo 1: el de los millones
    +            if decena == 1:
    +                subcadena = " MILLON "
    +            elif lista[i] > 1:
    +                subcadena = " MILLONES "
    +            else: #aqui se entra si lista[i] == 0 y en ese caso, no hay nada que procesar
    +                continue #se sigue con la siguiente iteracion del bucle
    +
    +        elif i == 1: #grupo2: el de los miles
    +            if lista[i] == 1:
    +                cadena += " MIL "
    +                continue #se pasa a la siguiente iteracion
    +            elif lista[i] > 1:
    +                subcadena = " MIL "
    +            else: #aqui se entra si lista[i] == 0 y en ese caso, no hay nada que procesar
    +                continue #se sigue con la siguiente iteracion del bucle
    +
    +        elif i == 3 and lista[i] != 0: #grupo4: el de los centavos (decimales)
    +            cadena += " CON "
    +            subcadena = " CENTAVOS"
    +
    +        if centena != 0:
    +            if centena == 1 and (unidad + decena) == 0:
    +                cadena += numeros[100]
    +                continue
    +            elif centena == 1:
    +                cadena += "CIENTO "
    +            elif centena == 5:
    +                cadena += numeros[500]
    +            elif centena == 7:
    +                cadena += numeros[700]
    +            elif centena == 9:
    +                cadena += numeros[900]
    +            else:
    +                cadena += numeros[centena] + "CIENTOS "
    +
    +        if decena != 0:
    +            if decena < 21:
    +                cadena += numeros[decena]
    +            elif decena < 30:
    +                cadena += "VENTI"+numeros[unidad]
    +            else:
    +                cadena += numeros[(decena/10)*10]
    +                if unidad > 0:
    +                    cadena += " Y "+numeros[unidad]
    +
    +        cadena += subcadena
    +
    +    return cadena
     

    Autor / Autores:

    CesarPortela

    diff --git a/recetario/autocomplecionenconsolainteractiva/index.html b/recetario/autocomplecionenconsolainteractiva/index.html index 1a647773a..348dd6213 100644 --- a/recetario/autocomplecionenconsolainteractiva/index.html +++ b/recetario/autocomplecionenconsolainteractiva/index.html @@ -29,7 +29,7 @@ import readline excep'> - + Ir al contenido principal @@ -63,12 +63,12 @@ - +
    @@ -89,27 +89,27 @@

    Autocomplecion En Consola Interactiva

    (donado por Anthony Lenton)

    Crear un archivo llamado .pythonrc (se llama así pero podría llamarse de cualquier otra forma), que dice:

    -
    if __name__ == "__main__":
    -   try:
    -       import readline
    -   except ImportError:
    -       print "Module readline not available."
    -   else:
    -       import sys
    -       import rlcompleter
    -       if sys.platform == "darwin":
    -          readline.parse_and_bind ("bind ^I rl_complete")
    -       else:
    -            readline.parse_and_bind("tab: complete")
    -       del readline
    -       del rlcompleter
    -       del sys
    +
    if __name__ == "__main__":
    +   try:
    +       import readline
    +   except ImportError:
    +       print "Module readline not available."
    +   else:
    +       import sys
    +       import rlcompleter
    +       if sys.platform == "darwin":
    +          readline.parse_and_bind ("bind ^I rl_complete")
    +       else:
    +            readline.parse_and_bind("tab: complete")
    +       del readline
    +       del rlcompleter
    +       del sys
     

    Y en el environment se setea la variable:

    -
    PYTHONSTARTUP=/home/tuusuario/.pythonrc #(aca importa que sea igual al nombre del alchivo).
    +
    PYTHONSTARTUP=/home/tuusuario/.pythonrc #(aca importa que sea igual al nombre del alchivo).
     

    Lo que hace es darte Tab-completion en el interprete, cuando no se recuerda que métodos tiene mistring, en el intérprete se hace:

    -
    >>> mistring.<tab><tab>
    +
    >>> mistring.<tab><tab>
     

    Lista los métodos y atributos disponibles.

    Otros intérpretes ya lo hacen. ipython es notable por tener todo esto y mucho más, pero hay gente que no se acostumbra a usarlo todavia, y esto le pone Tab-completion al intérprete que es bastante común.

    diff --git a/recetario/bloquearclickdelmouse/index.html b/recetario/bloquearclickdelmouse/index.html index f57afcf01..5bc094ced 100644 --- a/recetario/bloquearclickdelmouse/index.html +++ b/recetario/bloquearclickdelmouse/index.html @@ -28,7 +28,7 @@ #!/usr/bin/env python # -*- coding: utf-"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    @@ -91,20 +91,20 @@

    Bloquear Click Del Mouse

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -import os
    -import time
    -#
    -kb = file('/dev/console')
    -while True:
    -    os.system('xmodmap -e "pointer = default"') # Aca lo activamos
    -    kb.read(3)
    -    os.system('xmodmap -e "pointer = 0 2 3"') # Aca lo desactivamos
    -    time.sleep(0.5) # duerme, prueba reducir este valor para mas reaccion
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +import os
    +import time
    +#
    +kb = file('/dev/console')
    +while True:
    +    os.system('xmodmap -e "pointer = default"') # Aca lo activamos
    +    kb.read(3)
    +    os.system('xmodmap -e "pointer = 0 2 3"') # Aca lo desactivamos
    +    time.sleep(0.5) # duerme, prueba reducir este valor para mas reaccion
     

    Ejemplo:

    -
    sudo /usr/bin/env python blockclick.py
    +
    sudo /usr/bin/env python blockclick.py
     
    @@ -91,187 +91,187 @@

    Boton Grafico Tk

    • Requisitos: Es necesario saber usar encoding en Base64, que NO es cubierto por esta Receta, disculpe.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -# Esto es okbutton.py
    -import Tkinter
    -
    -class OkButton(Tkinter.Button):
    -    def __init__(self, master, data = 0, *args, **kwargs):
    -            if data:
    -                self.onImage = Tkinter.PhotoImage(data = kwargs['onImage'])
    -                self.offImage = Tkinter.PhotoImage(data = kwargs["offImage"])
    -                self.activeImage = Tkinter.PhotoImage(data = kwargs["activeImage"])
    -            else:
    -                self.onImage = Tkinter.PhotoImage(file = kwargs['onImage'])
    -                self.offImage = Tkinter.PhotoImage(file = kwargs["offImage"])
    -                self.activeImage = Tkinter.PhotoImage(file = kwargs["activeImage"])
    -            del kwargs['activeImage'], kwargs["onImage"], kwargs["offImage"]
    -            Tkinter.Widget.__init__(self, master, 'button', kwargs, args)
    -            self.bind("<Enter>", self.mouseOver)
    -            self.bind("<Leave>", self.mouseLeave)
    -            self.bind("<Button-1>", self.mouseClick)
    -            self.bind("<ButtonRelease-1>", self.mouseLeave)
    -            self.mouseLeave(None)
    -    def mouseOver(self, Event):
    -        self["image"] = self.onImage
    -    def mouseLeave(self, Event):
    -        self["image"] = self.offImage
    -    def mouseClick(self, Event):
    -        self["image"] = self.activeImage
    -
    -oexitOff = '''\
    -R0lGODlhXgAiAOf/AAABAAYAAAQABgUCBw0ACBMACRQACxUBDBMCEgkGDBAEDBkCFBYEDhsDEBIH
    -DxwFERgHERwGEhsHFx8HGBUMEhoLEyEKGh8MFRcPFB4OGyINGycMHR0QFyMOHCQPHR0SHCUQHh4U
    -HiMTHysRISAVIC0SIiQVICkUIi4TIyYWIioVIy4UJCIYIi8UJScXIzEWJi4YJioaJjQYKSsbKDIZ
    -LSwcKTEbKi4eKjkdLjAgLDIhLjkfNDwgMDwiNzYlMj4jODwlNEAkNTgnND8lOjopNj8oN0MnN0Io
    -PUUoOUEqOT4tOkQtO0csQUYvPkguQ0suP0QwQ0ovRUkxQEswRk4xQkozQkY1QlIxSEw0Q04zSEg2
    -Q001RE42RVA1SlM1Rko4RVU3SFE5SFQ4Tkw7SFU5T1o4UFc7UVc8UVo8TlY+TVJATWA+VlNES1pC
    -UWJAWGNBWWRCWmBEWllHVWZEXGJGXFdLV2ZHWWlGXmpHYGVJX1pNWWFMVWtIYWBNW2hLYW1KYmBR
    -WG9MZF5SXnFOZmZTYXJPaG5RaGJWYnZSa2pXZXNVbG1YYXhUbXlVbm1aaGtcY25baXtXcHxYcXha
    -cXBda31Zcn9bdIZbdoFddn1fdohdeIRfeXNmcopfeoxgfI5ifollfntrcpBkgItmgHpteZJmgo1o
    -gpRohJZqhpFshZdrh5ltiZVviZhuj4N2god3f55xjZhzjZxylKBzj5t1j6F0kIx8hIt9ip13kaN2
    -kox+i6J3maV4lKZ5laR5m6J8lqZ7nZODi6t9mql+oKp/oZeHj62CpLCCn5uKkq+EprWDp7GGqLmG
    -q7SJq7uIrZ+Sn7aLrbeMrqWUnL+MsbmOsLuQsqiYn8GPs6SaoKmZoMSRtaycpMaTt8eUuKmgpsiV
    -ucOXucmWu8qXvMuYvc2av86bwLalrdCcwdGdwrSqsNOfxNSgxdWhxtaiyNekydilyrqwt9qmy9un
    -zMC2vMq5wcS7wdfN09rQ1tzS2OHX3ufd4+rg5u7k6vvw9/7//P///yH+EUNyZWF0ZWQgd2l0aCBH
    -SU1QACH5BAEKAP8ALAAAAABeACIAAAj+AAEIHEiQYAACBRIqXMiwocOHECM6JBCgoMWLFyVq3Mix
    -o0OMIAdGjNBBQoOTKFOqXMmypUuVEko2YPAwpMWIEGCoSSSojs+fQIMKHUq0aFBBjwTJ+XKiQU2b
    -ACAe8PAl1Lx8+fBp3cq1q9evYMN2zacv3z14nLSIOPAxpFQRerzd6+evrt27ePPq3cu3r79+9rbp
    -ado248OpbKTZ28evsePHkCNLnky5suN99qT1EZKBLUPDDzNoeWWuHr3TqFOrXs26tevXqOvJTocs
    -lJULhUU6PMAghqNi0rIJH068uPHjyJMrN47N2rNgiWLQ/ExwNwIGD24ccnXrlq7v4MP+ix9Pvrz5
    -8+C737L1ihQg6bkZHrje4IEEFVL6JHLkCBIlSpAEKOCABBZo4IEIEvgfJPwtkgghe4wBhAcMIOCZ
    -QropxNsCD0zQwQYl4FAEFFJQwUUYXGCh4oostujiizDG2OKJXFAhxRNLJAGEDSdY8MACDFyYkEAL
    -8daABBZ4gIIMOPyABBNRTJFFF1lcYeWVWGap5ZZcdpnllFNMEQUTSPywgwwoeGCBSUEuRGRCB3Do
    -YQk08HBEFGCcscYbc9zh55+ABirooHfEIYYZfRKqaKBzvLHGGWBEcQQPNJTQwQQ/XghAAHBiN8EG
    -KOBwxBRnwPFHIY1UYgkmm2yiyav+sMYq66ywekEAQRz8QSuscwBgQqyXmABADZZU0kghf8BxxhRH
    -4IDCBpi2WcBBBfDW4QYv8MAEGXMUIkknpaCyCiyy1GLuuegaokMNjKDrbi2zxCBQBT7kUBEAebx7
    -LiIAfICuDwBg0Aosq6BSSieSFDIHGUzw8AK0D7SJUAEILBATCtqecUcknahSCzDDHKPMMiQ3Y/LJ
    -ySQhkADDnOzyyVwIlMrJy7Qh88snbwJACidjAQAFwyyjzDHDAFOLKp1EcscZDaNQ0gIIaMihBSEy
    -cUYglpxSizDLODONNtpw083YZHejzQ0DDVP22t0YIxAtbEsBQAxsj53K3GOn8XP+NN1wA/Y0ziwz
    -TC2nWBII0ziU4OMCbBGAQAMTeECDEWTcYQkqviRDjTbfjENOOaCjI/roKguEy+ioo04HADmkLvo0
    -AkXjOjqxAHADOjZToA06oJdDzjjfaENNMr6gYskdZBhBgwcTNIAARdh1gPEUcERyii/LXPMNOeio
    -w8734IPvx0CghG8++DkAoMj533MAwCjs08J67uCcrw465HxzzTK+nBIJHFPggdMiVhGLdUAGRyjD
    -IDpRi2RorxzeA1884qGNNiQhHrkYiB0myMEOdpACAEiFBzkoBPWNMB64IMg3PBg+dZRDf8moRScG
    -UYYjyOBpAoFciKIAB0moYhj+1PhGOb43QiLI7F4+OOEJQcgKJRYBAIg4YQYFIJAQrPCE33shNYah
    -CknAIQqJa55AHmABFPSgC3fQxCyUoQ1yeI+D8oijPLZQEAegQ454zGMcawAAS+gxjiR43x95wbpv
    -sAAACdBGHjnIDnWQQxvKmIUm7tCFHqDARwIJgPSCQIZAfGIXzOgGOtgxQT2CoiDN+KMq4wAAJfzx
    -HAKpxiBZJw92qEwA3NDjBNmBjm4wYxefCAQZguC0ewGgAy/4QRkKIYpeROMboyxlHtFBkEyoUpXQ
    -iKUex0cCVRIyB3GMRxMA4IByLDIevPxGNHohikKU4Qcv6ABBBJDMZTbzmdH+jMcf9UbLa6oyZrrD
    -oykE8gtv9lMe8UhfDfQpx12iQ53sdCc8qUgQFXDSk6AUJSkZushhEIOj/swjO+QFgCYYIg8pEMgk
    -rvlNPJ5DAQCgAx4d6ktgCjMIKrjIGdO4xja+UZohDaoc2WGIgnwgF/5sKR6XIRBiIHSXjoSkJCnZ
    -A4wIgIc+BKIQiajErnrVg8uIRS208dWydjCL39hiF79I0YsoQIEMdKAQI8hVs9r1rmVt4QuvEcMZ
    -lgGmISGAG6yHPe1xj67sS6xiF8vYxt4vf/vrXyTccCuoAKAIl8vc5jr3udDN7rOgDa1oXde73wVv
    -eMWzxBMtOxACeEFrXPM3GtjEVrfa2va2uK2t37QBOMERzlasvYgL0FCJVoRsZCXDmXKXy9zmMpdk
    -QjuGMFpRCTS4ACoBAQA7
    -'''
    -oexitOn = '''\
    -R0lGODlhXgAiAOf/AAABAAYAAAcAAAkBAA0ACBAAARUAARYAAxQACxkADB0ADRoBDRwAFB4ADyIA
    -ER8BECEAFSUAEiQAFiQAFygAGCUBFywAGSsAHS0AGiIEFyYEGSoDGi4CICgHGzAFIzIHJCwMHzUJ
    -JzsIKTYKJzwJKhYA/zAQIhsA/z4LLB8A/yIA/0ANLT0PKEcMMUEPL0kQMwQQ/0AUMTkYKk0TNkcV
    -NDwaLUwUO0QYNFAWOS4N/08XPlcVPFAYP0kcOVkXPkoeOjMR/1gZRFkaREwgPFobRTYT/0QkO04h
    -PlkZflgfRlEciEUoOV4fSVEkQEsT/0soO2YfTWEiTGQfYmghT04X/04rPk4c2mMkTmUjWWojUGwl
    -UkMg/2smWFEzRFMg/3ApVm8qXGImsVQ2R1Yj/3EsXlgk/3AnnWUk/30uX1o8TV8r53wwZGcn/30x
    -ZX4yZmE9UF4/UYAzZ20v0WEv/3QvzYI1amBCU4o1bYU4bG4w/3Q0yGRFV4w3b3Az/2ZHWI45cWxH
    -W5A7c3w0/2xJYoY22ZI9dYw/c25LY3BLXmdOXn43/2xNXpQ/d3BNZZRBfZdBeZZDf5pCh51Cgos7
    -/5pEfJI/x41AzYM//59EhKFEf41C6o5C/51KhqRIiKVJinRba5hD8JFE/6ZKi55H2KdMjJhF/5xG
    -83lfb6hLq55I56lOjp9J9qtQkKtQoqVK8q1Skq1Nx7RRlLJRmrZSlqZP77BRvrdTl6tP6rVUnLlW
    -mb1UsoVre7FU4bxYm8NXnr5anbtV2bdW37hZxsNapr1aw8JbrItwgcZcqMJeoYxygsJcv8ddqb1c
    -18heqsJd08VdzsVfwspgrMxgp8peys1irs9ksJJ7hctkyNBmss9lxJd8jNJotNlmttRnwddnu9Np
    -tdpnt9tpuNxquZeDkd1rup6KmaCMm6KOnaaPmKWQn6iToqqVpLKdrbWgsLumtcCvt8mxu8iywtPE
    -0tfFzdbI1drI0dzL0+LQ2OjX3+vZ4e7c5PDe5/nq+P3r8/78/////yH+EUNyZWF0ZWQgd2l0aCBH
    -SU1QACH5BAEKAP8ALAAAAABeACIAAAj+AAEIHEiQoIABBxIqXMiwocOHECM2LDBAQMGLGDFK3Mix
    -o0eHGUMOjLgAQoMEKFOqXMmypcuXKxuYTIDgociLBSAmANEl0Z40QIMKHUq0qNGjQ/f4TPOkQwKH
    -BW4KhIhAw5NT7+7ds8e1q9evYMOKHfv1Hr579dx9elKhZsObVDXAWUevn7+7ePPq3cu3r9+//vjJ
    -UwfHKciMVDOIKTcvn77HkCNLnky5suXLkPPNKwdHBgS3CzHmfMhgyS528OKpXs26tevXsGPLXg2v
    -drtxp5YwmHiRKohF2syhS0e8uPHjyJMrX868OLrn6cpZSwQCtMKCDxEgWGDCz65k4MP+ix9Pvrz5
    -8+jNG9t1yk71w1MZak+woMEGI28ADRp0qBGi/QAGKOCABBZo4ICINHLIfoD44ccbVdTQlnUJjSQf
    -fQ04UAEGI8TQww8/DNHEEUOUaOKJKKao4oosonhEE0OA2MMNN7DwwQYPLEDTWwBc2MADG3ogAgkt
    -0DDDDDjwoAMPTDbp5JNQRinllE8uicORNLSwgggeYFDBAydRGF9C2zUQJJEz7EAEE1BMkcWbcMYp
    -55x0ZiGFEkhgUeeec04BBRNE7DBDCyR0WUEDC1gHgAAKlbnhCCvYQMQVXJCBhhtxxIHHppx26umn
    -nlqhwqikmgEqp2GM6umoMMThBhr+ZHBxBRE2rDCCl4iCdhCZ9VXAgQgv7DAFGG3cEQgjkEgiSSaZ
    -cOLss87KAQQMekBrLSeSwEBqEUCQqsa1z9IxKrRFjBqJJJAwEsgdbYAxxQ4viMDBoYkmNEBOCCRg
    -JgbAEqHFGnw8wgkprLwSy8Gx2KLwwrKUOyoqC0e8MBWjWsJwGaNWIvHChIw68aitHPwKK6Rw8ggf
    -a2hBRLy47lgAvgs8wOELRHwRRyGcsBJLLr8Mg8wxxywj9NDFdDsqLEMnPXQto46i9DJOqADD00Jr
    -IrXQY4yqC9DIDPNLLrGowkkhcXyx8q051vRyvmZ6sMIOWsTBSCex9IJMM9FQQw3+Nnz3zbfDKqTi
    -9+B8s6ECEIRjQ8yowiRuyuHYYKyCMn3rHU0zyPQSSyeMxKHFDit4cChNBQiwnQMYkGDDFWsUQrcv
    -zey9zTbc1G577XOQesntvNvebR+91z7qJME/DoTk0PA+OzbUNOPL5oWscYUNJGDgQKIW6RuB20KA
    -wQcnsfgiDTa0h2O++c+UUUQ4rpDKxvnwxx/OqJvIb365fdi/CqkqTGN/ONzYBjak8TxO8AEMQghd
    -BE4iEH1RYAQzgEIbHKGKXjQDG984nzg2KA6HbWJbHAyhCDc4qlKMcIP4O+H++DeNEZ7vG9hoRi9U
    -4Yg2QGEGI6AAAwEQs9TxQAv+eJBELIZBjW2Yb4PkSCI5tsC/UWVDiVCMYhK7pQgpJnFUl7Di/oAw
    -DVI5I4obNN82qDGMWEgCD1rgQfVyNBAHcIAEO/gCHzqBi2VggxvhEIcUL9HEYFjxj4YrghWzMSpm
    -aPFw5PCGw54hRXEAEBvLwEUn+PCFHZCAAw4giBtXIAQyGIIUFrxjHqVISFJV8Y9WBEYhpZg7Ffxx
    -i0kMR9RUcA0wPlKGpDAEGRKISYNwgJOeBOUF8ahHKUoOCKhEJRNV8EUlflAFrnglImPZLSCEA4qO
    -5EYMe5HLXa6AAxYhyAXgKEc62pGYVgzHLW5xzWRasRvaUoET8sCGeAoClbDtVGIp2YDNR0ZykpUk
    -wQUwQoIfBnGIRTxiMd3JUCWGIw9NVMEqkplPJfJiVLcgRxjDMcYynjGNJMiIACI4wQpeMIMKPaFK
    -VypCXpRiFc9gqUxD+MJt0tCGMwgnRgjQve+Fb3zl+59Qh0rUohI1gAMs4AGFQICbDCAKrXtd7MhH
    -u+BZ9apYzapWl9e853UielEYgFQEsgK50c1ueNNb4tbK1ra61a2Ww5zmOBeHFYyVIATgAc50xjOf
    -AY1qgA2sYAf7NKAdo2tfC9vYeNDUu15EA0lwAyUKhrCEbeyymM2sZjNb2VeQghJuSIIGpBIQADs=
    -'''
    -oexitActive = '''\
    -R0lGODlhXgAiAOffAEpLSU1LT09LSlVKS05MT1BMSlRLUFlKUlRMUVpLUl5KU1tMU11LWFpNWVxN
    -VF5MWV1OVV9NWmBOW0lMtVJKtl9QV2FPXGJPXWRPWFNLt2BRWFpKsmNQXmhPX1tLs2ZRWmlQYFxM
    -tGVSYGpRYV1NtWZTYWtSYmRVXF5OtmdUYmRWXVdRtl9Pt2hVY1lRt21UZGlWZG5VZWpXZW9WZmhZ
    -YWFTtGtYZnBXZ2laYWJUtWxZZ25WgnFYaGpbYnJWfmNVtm1aaHJZaXNYdGlVsmRWt3ZYb3hYanNa
    -amxdZGpWs3lZa2tYonRba2tXtHpabG5fZnZdbW1ZtnxcbnNblHtddGtjaG9at3tbinFiaXRas3Jj
    -anVbtH1fdn9fcXdcqHNka3ZctX5gd3pennRlbH9heHtfn3VmbXhet4BieXFoboBfm4Fjen5fs3do
    -b39ftIJke3hpcIBgtYNlfHRrcX9jpHlqcYFhtoRmfXVscollfnprcoplf4hkm4tmgIZloYlnhYdj
    -s4Fls4xngYhktIJmtI1ogoplqXlwdolltY5pg4pmtoxnq4VotpBqhHtyeIpppY1orJFrhYFxeYlp
    -snxzeY5prZJshpRri5JrkYpqs49qrpNth5NrnphsiJRuiJNrqpltiZJumZVviZpuipZvlYF4fptv
    -i5lum5NvpppvnJ1wjJRwp5hwo4N6gJtxk55xjZ5wmJlxpIR7gZxxn59yjp9xmZ1yoKBzj550lp5z
    -oaF0kKFzm4d+hJ91l6J1kaJ0nIh/haF2mKN1naR3k6J3mYqBh6N4moyDiY2Eio6Fi4+GjJCHjZGI
    -jpWMkpaNk5iPlZySmJ2TmZ6UmqWboaacoqKfo6OgpKqhp6yjqa2kqqmnq6qorK6ssK+tsbWytv//
    -////////////////////////////////////////////////////////////////////////////
    -/////////////////////////////////////////////////////yH+EUNyZWF0ZWQgd2l0aCBH
    -SU1QACH5BAEKAP8ALAAAAABeACIAAAj+AAEIHEiQYIECAxIqXMiwocOHECM6PFiwokWLEjNq3MjR
    -4cWPAyMaSJDAgMmTKFOqXMmyZUqSJQ08BFlRZIUnc9Jo2cmzp8+fQIMK9ZkGTxosPSDI9EgTAEQD
    -C3pIgnbtmrWrWLNq3cq1q1et17Bdq/bsUI+STD8+XTCGGbVu3uLKnUu3rt27ePN64zZt2RilaWs+
    -HFkF2bRs2rYpXsy4sePHkCNL3qYt27RjY06gZYgRYoIepZpFk0a6tOnTqFOrXs36dDRnxRzhSBBY
    -4NMKeoAhU8a7t+/fwIMLH048eLJjvOZUWLqw4GCTGtqUakW9uvXr2LNr3859eylKZpb+B26Y0gGN
    -MXDS19FTp7379/Djy59PXz779OnbfEGi2WTDkAydBBMDGJQAgwwy6ACEDgw26OCDEEYo4YQRLoig
    -DC2k8IEEDMTEnEK2LSRgAgxEYAEHIKRgggkvtOjiizDGKOOMNNYIw4opgMDBBRF06CFnTilkEkkl
    -XgCCCTHcwMMRRjChxJNQRinllFQKsYMPRVCpJZVMGHEEDzfEYAIIPProH4gIJTQkiRZ0YMINRzhB
    -RRdhkIHGnWvkqeeefPap5xITBBpoBlf4qecUE4SwJxohTIACGWF0QYUTR9xgQgcWmMncQWqOlMAD
    -FowQgxFShLGGHHns0YcgrBbi6qv+rorBAgpqwGprIYKgMGgNLAjqxa2vijGBB7DWMEEGf/SxRx5y
    -rBGGFEbEMIIFD5B0ZpoCMhDqDU5wscYehTRiiSWeeCKKKKCkq+4mOQiKibrwqttEoH6o24kVgfIR
    -r7p0JKpuEhNQcEm54zZSyB5rcOHEDdN2eJKII2k7wg1QkCFHIZZ0AooqHL/i8cceu+KCoJyAbPIr
    -oQT6yMkAo3Cyx4Y46jG+FJDiMceqgNJJJIXIQQYUDGcaU0IFrBlBBzE4QUYeiWwyiiq03KILLr5U
    -bXXV7QYKydVcV73FBC507UsqgZ4i9iJg+0IzLFbjossttKgyyiaJ5EGGEzF0EIH+tQYcNCQDF5hw
    -BBdyJOIJ1LpU3UswjDfOOBiCAuL45I2PzAbljG8wASGYQwI2zbVM3kvVusTtSSJycHGECRc43DcA
    -Qx59gxRrFLKJKrdUHQwxw/Q+TCpW5DBMJYJu4fvxyA9DwQSMJN+7sWw477mgtjhPTDBV36LKJoWs
    -IcUNesck0EgKWCB4GHlEMgotvuw+DDHGxG9M1ogIWoP8+Ocf//KK6B9/u2zwH/EEFQJb6I931/MF
    -LUYRiTyEYXUWUEBJxkeiC7zACWsQxOESRwz45W9eggrYL/znv5HFgYSNCoQAJ8CCXDSKAqnwXwd9
    -oQtVeEIQa3DCC1o3QYGQiAP+MZDCGxIBile0bxj+C0QIJ7AKEvovCxP4gf9+EShWrJAFxghG1gyo
    -v2Fg7xWgSMQbpBADDnSIIJ8CIhXk0Ij1HXGKIbSDE/23ikDFQn+QCwEJiYdFYxDjBwHbRRext8BG
    -yIEKZayWQR6gRja6MRhI9B++WDhHEs4LhvgbRKA0sUdKxo8YvXKBB+XnRQWOwpCI5MADClAQBgBR
    -iEQ0IiRJSIxPfGKUlcRfMHQ1gSGcYQskCJQbnMhH/P1ieVvIXynBKEYymtEiFsSgBlXBQVzm8pp+
    -PMMSPZCJORYTf6gI1CfkN8Ma3jCHO7xIAc6XvkciEJvwjB8qJpGJGMaTlu+ZIyQDHbg6Vl6EALOr
    -3e1y1z7eOe+gCE2oQhfauwT6Qnvc894NCECTAgSBcIZDnOIwx9GOevSjIA3G6GhoOtRxIQj+bIoI
    -lta0p0VtamKLqUxnSlOaug1ucqOb3UTQlIIEIAYXy9jGOvayohr1qEg9Ks50xjM5xCAAPb1IA24Q
    -hj6Mq1zn2pdWt8rVrnb1XARrRB/CcIMGNCUgADs=
    -'''
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +# Esto es okbutton.py
    +import Tkinter
    +
    +class OkButton(Tkinter.Button):
    +    def __init__(self, master, data = 0, *args, **kwargs):
    +            if data:
    +                self.onImage = Tkinter.PhotoImage(data = kwargs['onImage'])
    +                self.offImage = Tkinter.PhotoImage(data = kwargs["offImage"])
    +                self.activeImage = Tkinter.PhotoImage(data = kwargs["activeImage"])
    +            else:
    +                self.onImage = Tkinter.PhotoImage(file = kwargs['onImage'])
    +                self.offImage = Tkinter.PhotoImage(file = kwargs["offImage"])
    +                self.activeImage = Tkinter.PhotoImage(file = kwargs["activeImage"])
    +            del kwargs['activeImage'], kwargs["onImage"], kwargs["offImage"]
    +            Tkinter.Widget.__init__(self, master, 'button', kwargs, args)
    +            self.bind("<Enter>", self.mouseOver)
    +            self.bind("<Leave>", self.mouseLeave)
    +            self.bind("<Button-1>", self.mouseClick)
    +            self.bind("<ButtonRelease-1>", self.mouseLeave)
    +            self.mouseLeave(None)
    +    def mouseOver(self, Event):
    +        self["image"] = self.onImage
    +    def mouseLeave(self, Event):
    +        self["image"] = self.offImage
    +    def mouseClick(self, Event):
    +        self["image"] = self.activeImage
    +
    +oexitOff = '''\
    +R0lGODlhXgAiAOf/AAABAAYAAAQABgUCBw0ACBMACRQACxUBDBMCEgkGDBAEDBkCFBYEDhsDEBIH
    +DxwFERgHERwGEhsHFx8HGBUMEhoLEyEKGh8MFRcPFB4OGyINGycMHR0QFyMOHCQPHR0SHCUQHh4U
    +HiMTHysRISAVIC0SIiQVICkUIi4TIyYWIioVIy4UJCIYIi8UJScXIzEWJi4YJioaJjQYKSsbKDIZ
    +LSwcKTEbKi4eKjkdLjAgLDIhLjkfNDwgMDwiNzYlMj4jODwlNEAkNTgnND8lOjopNj8oN0MnN0Io
    +PUUoOUEqOT4tOkQtO0csQUYvPkguQ0suP0QwQ0ovRUkxQEswRk4xQkozQkY1QlIxSEw0Q04zSEg2
    +Q001RE42RVA1SlM1Rko4RVU3SFE5SFQ4Tkw7SFU5T1o4UFc7UVc8UVo8TlY+TVJATWA+VlNES1pC
    +UWJAWGNBWWRCWmBEWllHVWZEXGJGXFdLV2ZHWWlGXmpHYGVJX1pNWWFMVWtIYWBNW2hLYW1KYmBR
    +WG9MZF5SXnFOZmZTYXJPaG5RaGJWYnZSa2pXZXNVbG1YYXhUbXlVbm1aaGtcY25baXtXcHxYcXha
    +cXBda31Zcn9bdIZbdoFddn1fdohdeIRfeXNmcopfeoxgfI5ifollfntrcpBkgItmgHpteZJmgo1o
    +gpRohJZqhpFshZdrh5ltiZVviZhuj4N2god3f55xjZhzjZxylKBzj5t1j6F0kIx8hIt9ip13kaN2
    +kox+i6J3maV4lKZ5laR5m6J8lqZ7nZODi6t9mql+oKp/oZeHj62CpLCCn5uKkq+EprWDp7GGqLmG
    +q7SJq7uIrZ+Sn7aLrbeMrqWUnL+MsbmOsLuQsqiYn8GPs6SaoKmZoMSRtaycpMaTt8eUuKmgpsiV
    +ucOXucmWu8qXvMuYvc2av86bwLalrdCcwdGdwrSqsNOfxNSgxdWhxtaiyNekydilyrqwt9qmy9un
    +zMC2vMq5wcS7wdfN09rQ1tzS2OHX3ufd4+rg5u7k6vvw9/7//P///yH+EUNyZWF0ZWQgd2l0aCBH
    +SU1QACH5BAEKAP8ALAAAAABeACIAAAj+AAEIHEiQYAACBRIqXMiwocOHECM6JBCgoMWLFyVq3Mix
    +o0OMIAdGjNBBQoOTKFOqXMmypUuVEko2YPAwpMWIEGCoSSSojs+fQIMKHUq0aFBBjwTJ+XKiQU2b
    +ACAe8PAl1Lx8+fBp3cq1q9evYMN2zacv3z14nLSIOPAxpFQRerzd6+evrt27ePPq3cu3r79+9rbp
    +ado248OpbKTZ28evsePHkCNLnky5suN99qT1EZKBLUPDDzNoeWWuHr3TqFOrXs26tevXqOvJTocs
    +lJULhUU6PMAghqNi0rIJH068uPHjyJMrN47N2rNgiWLQ/ExwNwIGD24ccnXrlq7v4MP+ix9Pvrz5
    +8+C737L1ihQg6bkZHrje4IEEFVL6JHLkCBIlSpAEKOCABBZo4IEIEvgfJPwtkgghe4wBhAcMIOCZ
    +QropxNsCD0zQwQYl4FAEFFJQwUUYXGCh4oostujiizDG2OKJXFAhxRNLJAGEDSdY8MACDFyYkEAL
    +8daABBZ4gIIMOPyABBNRTJFFF1lcYeWVWGap5ZZcdpnllFNMEQUTSPywgwwoeGCBSUEuRGRCB3Do
    +YQk08HBEFGCcscYbc9zh55+ABirooHfEIYYZfRKqaKBzvLHGGWBEcQQPNJTQwQQ/XghAAHBiN8EG
    +KOBwxBRnwPFHIY1UYgkmm2yiyav+sMYq66ywekEAQRz8QSuscwBgQqyXmABADZZU0kghf8BxxhRH
    +4IDCBpi2WcBBBfDW4QYv8MAEGXMUIkknpaCyCiyy1GLuuegaokMNjKDrbi2zxCBQBT7kUBEAebx7
    +LiIAfICuDwBg0Aosq6BSSieSFDIHGUzw8AK0D7SJUAEILBATCtqecUcknahSCzDDHKPMMiQ3Y/LJ
    +ySQhkADDnOzyyVwIlMrJy7Qh88snbwJACidjAQAFwyyjzDHDAFOLKp1EcscZDaNQ0gIIaMihBSEy
    +cUYglpxSizDLODONNtpw083YZHejzQ0DDVP22t0YIxAtbEsBQAxsj53K3GOn8XP+NN1wA/Y0ziwz
    +TC2nWBII0ziU4OMCbBGAQAMTeECDEWTcYQkqviRDjTbfjENOOaCjI/roKguEy+ioo04HADmkLvo0
    +AkXjOjqxAHADOjZToA06oJdDzjjfaENNMr6gYskdZBhBgwcTNIAARdh1gPEUcERyii/LXPMNOeio
    +w8734IPvx0CghG8++DkAoMj533MAwCjs08J67uCcrw465HxzzTK+nBIJHFPggdMiVhGLdUAGRyjD
    +IDpRi2RorxzeA1884qGNNiQhHrkYiB0myMEOdpACAEiFBzkoBPWNMB64IMg3PBg+dZRDf8moRScG
    +UYYjyOBpAoFciKIAB0moYhj+1PhGOb43QiLI7F4+OOEJQcgKJRYBAIg4YQYFIJAQrPCE33shNYah
    +CknAIQqJa55AHmABFPSgC3fQxCyUoQ1yeI+D8oijPLZQEAegQ454zGMcawAAS+gxjiR43x95wbpv
    +sAAACdBGHjnIDnWQQxvKmIUm7tCFHqDARwIJgPSCQIZAfGIXzOgGOtgxQT2CoiDN+KMq4wAAJfzx
    +HAKpxiBZJw92qEwA3NDjBNmBjm4wYxefCAQZguC0ewGgAy/4QRkKIYpeROMboyxlHtFBkEyoUpXQ
    +iKUex0cCVRIyB3GMRxMA4IByLDIevPxGNHohikKU4Qcv6ABBBJDMZTbzmdH+jMcf9UbLa6oyZrrD
    +oykE8gtv9lMe8UhfDfQpx12iQ53sdCc8qUgQFXDSk6AUJSkZushhEIOj/swjO+QFgCYYIg8pEMgk
    +rvlNPJ5DAQCgAx4d6ktgCjMIKrjIGdO4xja+UZohDaoc2WGIgnwgF/5sKR6XIRBiIHSXjoSkJCnZ
    +A4wIgIc+BKIQiajErnrVg8uIRS208dWydjCL39hiF79I0YsoQIEMdKAQI8hVs9r1rmVt4QuvEcMZ
    +lgGmISGAG6yHPe1xj67sS6xiF8vYxt4vf/vrXyTccCuoAKAIl8vc5jr3udDN7rOgDa1oXde73wVv
    +eMWzxBMtOxACeEFrXPM3GtjEVrfa2va2uK2t37QBOMERzlasvYgL0FCJVoRsZCXDmXKXy9zmMpdk
    +QjuGMFpRCTS4ACoBAQA7
    +'''
    +oexitOn = '''\
    +R0lGODlhXgAiAOf/AAABAAYAAAcAAAkBAA0ACBAAARUAARYAAxQACxkADB0ADRoBDRwAFB4ADyIA
    +ER8BECEAFSUAEiQAFiQAFygAGCUBFywAGSsAHS0AGiIEFyYEGSoDGi4CICgHGzAFIzIHJCwMHzUJ
    +JzsIKTYKJzwJKhYA/zAQIhsA/z4LLB8A/yIA/0ANLT0PKEcMMUEPL0kQMwQQ/0AUMTkYKk0TNkcV
    +NDwaLUwUO0QYNFAWOS4N/08XPlcVPFAYP0kcOVkXPkoeOjMR/1gZRFkaREwgPFobRTYT/0QkO04h
    +PlkZflgfRlEciEUoOV4fSVEkQEsT/0soO2YfTWEiTGQfYmghT04X/04rPk4c2mMkTmUjWWojUGwl
    +UkMg/2smWFEzRFMg/3ApVm8qXGImsVQ2R1Yj/3EsXlgk/3AnnWUk/30uX1o8TV8r53wwZGcn/30x
    +ZX4yZmE9UF4/UYAzZ20v0WEv/3QvzYI1amBCU4o1bYU4bG4w/3Q0yGRFV4w3b3Az/2ZHWI45cWxH
    +W5A7c3w0/2xJYoY22ZI9dYw/c25LY3BLXmdOXn43/2xNXpQ/d3BNZZRBfZdBeZZDf5pCh51Cgos7
    +/5pEfJI/x41AzYM//59EhKFEf41C6o5C/51KhqRIiKVJinRba5hD8JFE/6ZKi55H2KdMjJhF/5xG
    +83lfb6hLq55I56lOjp9J9qtQkKtQoqVK8q1Skq1Nx7RRlLJRmrZSlqZP77BRvrdTl6tP6rVUnLlW
    +mb1UsoVre7FU4bxYm8NXnr5anbtV2bdW37hZxsNapr1aw8JbrItwgcZcqMJeoYxygsJcv8ddqb1c
    +18heqsJd08VdzsVfwspgrMxgp8peys1irs9ksJJ7hctkyNBmss9lxJd8jNJotNlmttRnwddnu9Np
    +tdpnt9tpuNxquZeDkd1rup6KmaCMm6KOnaaPmKWQn6iToqqVpLKdrbWgsLumtcCvt8mxu8iywtPE
    +0tfFzdbI1drI0dzL0+LQ2OjX3+vZ4e7c5PDe5/nq+P3r8/78/////yH+EUNyZWF0ZWQgd2l0aCBH
    +SU1QACH5BAEKAP8ALAAAAABeACIAAAj+AAEIHEiQoIABBxIqXMiwocOHECM2LDBAQMGLGDFK3Mix
    +o0eHGUMOjLgAQoMEKFOqXMmypcuXKxuYTIDgociLBSAmANEl0Z40QIMKHUq0qNGjQ/f4TPOkQwKH
    +BW4KhIhAw5NT7+7ds8e1q9evYMOKHfv1Hr579dx9elKhZsObVDXAWUevn7+7ePPq3cu3r9+//vjJ
    +UwfHKciMVDOIKTcvn77HkCNLnky5suXLkPPNKwdHBgS3CzHmfMhgyS528OKpXs26tevXsGPLXg2v
    +drtxp5YwmHiRKohF2syhS0e8uPHjyJMrX868OLrn6cpZSwQCtMKCDxEgWGDCz65k4MP+ix9Pvrz5
    +8+jNG9t1yk71w1MZak+woMEGI28ADRp0qBGi/QAGKOCABBZo4ICINHLIfoD44ccbVdTQlnUJjSQf
    +fQ04UAEGI8TQww8/DNHEEUOUaOKJKKao4oosonhEE0OA2MMNN7DwwQYPLEDTWwBc2MADG3ogAgkt
    +0DDDDDjwoAMPTDbp5JNQRinllE8uicORNLSwgggeYFDBAydRGF9C2zUQJJEz7EAEE1BMkcWbcMYp
    +55x0ZiGFEkhgUeeec04BBRNE7DBDCyR0WUEDC1gHgAAKlbnhCCvYQMQVXJCBhhtxxIHHppx26umn
    +nlqhwqikmgEqp2GM6umoMMThBhr+ZHBxBRE2rDCCl4iCdhCZ9VXAgQgv7DAFGG3cEQgjkEgiSSaZ
    +cOLss87KAQQMekBrLSeSwEBqEUCQqsa1z9IxKrRFjBqJJJAwEsgdbYAxxQ4viMDBoYkmNEBOCCRg
    +JgbAEqHFGnw8wgkprLwSy8Gx2KLwwrKUOyoqC0e8MBWjWsJwGaNWIvHChIw68aitHPwKK6Rw8ggf
    +a2hBRLy47lgAvgs8wOELRHwRRyGcsBJLLr8Mg8wxxywj9NDFdDsqLEMnPXQto46i9DJOqADD00Jr
    +IrXQY4yqC9DIDPNLLrGowkkhcXyx8q051vRyvmZ6sMIOWsTBSCex9IJMM9FQQw3+Nnz3zbfDKqTi
    +9+B8s6ECEIRjQ8yowiRuyuHYYKyCMn3rHU0zyPQSSyeMxKHFDit4cChNBQiwnQMYkGDDFWsUQrcv
    +zey9zTbc1G577XOQesntvNvebR+91z7qJME/DoTk0PA+OzbUNOPL5oWscYUNJGDgQKIW6RuB20KA
    +wQcnsfgiDTa0h2O++c+UUUQ4rpDKxvnwxx/OqJvIb365fdi/CqkqTGN/ONzYBjak8TxO8AEMQghd
    +BE4iEH1RYAQzgEIbHKGKXjQDG984nzg2KA6HbWJbHAyhCDc4qlKMcIP4O+H++DeNEZ7vG9hoRi9U
    +4Yg2QGEGI6AAAwEQs9TxQAv+eJBELIZBjW2Yb4PkSCI5tsC/UWVDiVCMYhK7pQgpJnFUl7Di/oAw
    +DVI5I4obNN82qDGMWEgCD1rgQfVyNBAHcIAEO/gCHzqBi2VggxvhEIcUL9HEYFjxj4YrghWzMSpm
    +aPFw5PCGw54hRXEAEBvLwEUn+PCFHZCAAw4giBtXIAQyGIIUFrxjHqVISFJV8Y9WBEYhpZg7Ffxx
    +i0kMR9RUcA0wPlKGpDAEGRKISYNwgJOeBOUF8ahHKUoOCKhEJRNV8EUlflAFrnglImPZLSCEA4qO
    +5EYMe5HLXa6AAxYhyAXgKEc62pGYVgzHLW5xzWRasRvaUoET8sCGeAoClbDtVGIp2YDNR0ZykpUk
    +wQUwQoIfBnGIRTxiMd3JUCWGIw9NVMEqkplPJfJiVLcgRxjDMcYynjGNJMiIACI4wQpeMIMKPaFK
    +VypCXpRiFc9gqUxD+MJt0tCGMwgnRgjQve+Fb3zl+59Qh0rUohI1gAMs4AGFQICbDCAKrXtd7MhH
    +u+BZ9apYzapWl9e853UielEYgFQEsgK50c1ueNNb4tbK1ra61a2Ww5zmOBeHFYyVIATgAc50xjOf
    +AY1qgA2sYAf7NKAdo2tfC9vYeNDUu15EA0lwAyUKhrCEbeyymM2sZjNb2VeQghJuSIIGpBIQADs=
    +'''
    +oexitActive = '''\
    +R0lGODlhXgAiAOffAEpLSU1LT09LSlVKS05MT1BMSlRLUFlKUlRMUVpLUl5KU1tMU11LWFpNWVxN
    +VF5MWV1OVV9NWmBOW0lMtVJKtl9QV2FPXGJPXWRPWFNLt2BRWFpKsmNQXmhPX1tLs2ZRWmlQYFxM
    +tGVSYGpRYV1NtWZTYWtSYmRVXF5OtmdUYmRWXVdRtl9Pt2hVY1lRt21UZGlWZG5VZWpXZW9WZmhZ
    +YWFTtGtYZnBXZ2laYWJUtWxZZ25WgnFYaGpbYnJWfmNVtm1aaHJZaXNYdGlVsmRWt3ZYb3hYanNa
    +amxdZGpWs3lZa2tYonRba2tXtHpabG5fZnZdbW1ZtnxcbnNblHtddGtjaG9at3tbinFiaXRas3Jj
    +anVbtH1fdn9fcXdcqHNka3ZctX5gd3pennRlbH9heHtfn3VmbXhet4BieXFoboBfm4Fjen5fs3do
    +b39ftIJke3hpcIBgtYNlfHRrcX9jpHlqcYFhtoRmfXVscollfnprcoplf4hkm4tmgIZloYlnhYdj
    +s4Fls4xngYhktIJmtI1ogoplqXlwdolltY5pg4pmtoxnq4VotpBqhHtyeIpppY1orJFrhYFxeYlp
    +snxzeY5prZJshpRri5JrkYpqs49qrpNth5NrnphsiJRuiJNrqpltiZJumZVviZpuipZvlYF4fptv
    +i5lum5NvpppvnJ1wjJRwp5hwo4N6gJtxk55xjZ5wmJlxpIR7gZxxn59yjp9xmZ1yoKBzj550lp5z
    +oaF0kKFzm4d+hJ91l6J1kaJ0nIh/haF2mKN1naR3k6J3mYqBh6N4moyDiY2Eio6Fi4+GjJCHjZGI
    +jpWMkpaNk5iPlZySmJ2TmZ6UmqWboaacoqKfo6OgpKqhp6yjqa2kqqmnq6qorK6ssK+tsbWytv//
    +////////////////////////////////////////////////////////////////////////////
    +/////////////////////////////////////////////////////yH+EUNyZWF0ZWQgd2l0aCBH
    +SU1QACH5BAEKAP8ALAAAAABeACIAAAj+AAEIHEiQYIECAxIqXMiwocOHECM6PFiwokWLEjNq3MjR
    +4cWPAyMaSJDAgMmTKFOqXMmyZUqSJQ08BFlRZIUnc9Jo2cmzp8+fQIMK9ZkGTxosPSDI9EgTAEQD
    +C3pIgnbtmrWrWLNq3cq1q1et17Bdq/bsUI+STD8+XTCGGbVu3uLKnUu3rt27ePN64zZt2RilaWs+
    +HFkF2bRs2rYpXsy4sePHkCNL3qYt27RjY06gZYgRYoIepZpFk0a6tOnTqFOrXs36dDRnxRzhSBBY
    +4NMKeoAhU8a7t+/fwIMLH048eLJjvOZUWLqw4GCTGtqUakW9uvXr2LNr3859eylKZpb+B26Y0gGN
    +MXDS19FTp7379/Djy59PXz779OnbfEGi2WTDkAydBBMDGJQAgwwy6ACEDgw26OCDEEYo4YQRLoig
    +DC2k8IEEDMTEnEK2LSRgAgxEYAEHIKRgggkvtOjiizDGKOOMNNYIw4opgMDBBRF06CFnTilkEkkl
    +XgCCCTHcwMMRRjChxJNQRinllFQKsYMPRVCpJZVMGHEEDzfEYAIIPProH4gIJTQkiRZ0YMINRzhB
    +RRdhkIHGnWvkqeeefPap5xITBBpoBlf4qecUE4SwJxohTIACGWF0QYUTR9xgQgcWmMncQWqOlMAD
    +FowQgxFShLGGHHns0YcgrBbi6qv+rorBAgpqwGprIYKgMGgNLAjqxa2vijGBB7DWMEEGf/SxRx5y
    +rBGGFEbEMIIFD5B0ZpoCMhDqDU5wscYehTRiiSWeeCKKKKCkq+4mOQiKibrwqttEoH6o24kVgfIR
    +r7p0JKpuEhNQcEm54zZSyB5rcOHEDdN2eJKII2k7wg1QkCFHIZZ0AooqHL/i8cceu+KCoJyAbPIr
    +oQT6yMkAo3Cyx4Y46jG+FJDiMceqgNJJJIXIQQYUDGcaU0IFrBlBBzE4QUYeiWwyiiq03KILLr5U
    +bXXV7QYKydVcV73FBC507UsqgZ4i9iJg+0IzLFbjossttKgyyiaJ5EGGEzF0EIH+tQYcNCQDF5hw
    +BBdyJOIJ1LpU3UswjDfOOBiCAuL45I2PzAbljG8wASGYQwI2zbVM3kvVusTtSSJycHGECRc43DcA
    +Qx59gxRrFLKJKrdUHQwxw/Q+TCpW5DBMJYJu4fvxyA9DwQSMJN+7sWw477mgtjhPTDBV36LKJoWs
    +IcUNesck0EgKWCB4GHlEMgotvuw+DDHGxG9M1ogIWoP8+Ocf//KK6B9/u2zwH/EEFQJb6I931/MF
    +LUYRiTyEYXUWUEBJxkeiC7zACWsQxOESRwz45W9eggrYL/znv5HFgYSNCoQAJ8CCXDSKAqnwXwd9
    +oQtVeEIQa3DCC1o3QYGQiAP+MZDCGxIBile0bxj+C0QIJ7AKEvovCxP4gf9+EShWrJAFxghG1gyo
    +v2Fg7xWgSMQbpBADDnSIIJ8CIhXk0Ij1HXGKIbSDE/23ikDFQn+QCwEJiYdFYxDjBwHbRRext8BG
    +yIEKZayWQR6gRja6MRhI9B++WDhHEs4LhvgbRKA0sUdKxo8YvXKBB+XnRQWOwpCI5MADClAQBgBR
    +iEQ0IiRJSIxPfGKUlcRfMHQ1gSGcYQskCJQbnMhH/P1ieVvIXynBKEYymtEiFsSgBlXBQVzm8pp+
    +PMMSPZCJORYTf6gI1CfkN8Ma3jCHO7xIAc6XvkciEJvwjB8qJpGJGMaTlu+ZIyQDHbg6Vl6EALOr
    +3e1y1z7eOe+gCE2oQhfauwT6Qnvc894NCECTAgSBcIZDnOIwx9GOevSjIA3G6GhoOtRxIQj+bIoI
    +lta0p0VtamKLqUxnSlOaug1ucqOb3UTQlIIEIAYXy9jGOvayohr1qEg9Ks50xjM5xCAAPb1IA24Q
    +hj6Mq1zn2pdWt8rVrnb1XARrRB/CcIMGNCUgADs=
    +'''
     
    • Ejemplo: (es el de la foto).

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -# License: GPLv3
    -#import this
    -try:
    -    from Tkinter import *  # Python2
    -except ImportError:
    -    from tkinter import *  # Python3
    -################################################################
    -from okbutton import *  # This is the file, from the example ^_^
    -################################################################
    -root = Tk()
    -root.title('Boton')
    -root.focus()
    -root.resizable(0, 0)
    -botoncito = OkButton(root, 1, onImage = oexitOn, offImage = oexitOff, activeImage = oexitActive, bd = 0, relief='flat', cursor='hand2', command = root.destroy)
    -botoncito.pack()
    -root.mainloop()
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +# License: GPLv3
    +#import this
    +try:
    +    from Tkinter import *  # Python2
    +except ImportError:
    +    from tkinter import *  # Python3
    +################################################################
    +from okbutton import *  # This is the file, from the example ^_^
    +################################################################
    +root = Tk()
    +root.title('Boton')
    +root.focus()
    +root.resizable(0, 0)
    +botoncito = OkButton(root, 1, onImage = oexitOn, offImage = oexitOff, activeImage = oexitActive, bd = 0, relief='flat', cursor='hand2', command = root.destroy)
    +botoncito.pack()
    +root.mainloop()
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    diff --git a/recetario/bottle/galeria/index.html b/recetario/bottle/galeria/index.html index e5fadca7b..e3a6289d2 100644 --- a/recetario/bottle/galeria/index.html +++ b/recetario/bottle/galeria/index.html @@ -27,7 +27,7 @@ Usa Bottle para servir 1 página incrustada en la propia aplicacion, la misma desplega HTML, CSS y Js. #!/usr/bin/en"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - +
    @@ -89,104 +89,104 @@

    Mini Galeria De Imagenes Bottle

  • Cómo hacer una Mini Galería de Imágenes en Bottle, ejemplo basado en el Hola Mundo.

  • Usa Bottle para servir 1 página incrustada en la propia aplicacion, la misma desplega HTML, CSS y Js.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -from bottle import route
    -from bottle import run
    -from bottle import redirect
    -from bottle import debug
    -from bottle import error
    -from bottle import request
    -from bottle import abort
    -import os
    -#
    -GALLERY = """
    -<!DOCTYPE HTML>
    -<html>
    -  <head>
    -    <title>PYTHON-BOTTLE DEMO</title>
    -    <link rel="shortcut icon" href="http://python.org.ar/images/pyar.ico" type="image/x-icon"/>
    -    <meta http-equiv="X-UA-Compatible" content="chrome=1">
    -    <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
    -    <style type="text/css"> body { background-color: black; } </style>
    -<script language="JavaScript">
    -<!--
    -if (document.images) {
    -    demo1 = new Image();
    -    demo1.src = "http://www.gstatic.com/webp/gallery/5.webp";
    -    demo2 = new Image();
    -    demo2.src = "http://www.gstatic.com/webp/gallery/2.webp";
    -    demo3 = new Image();
    -    demo3.src = "http://www.gstatic.com/webp/gallery/3.webp";
    -    demo4 = new Image();
    -    demo4.src = "http://www.gstatic.com/webp/gallery/4.webp";
    -}
    -function timeimgs(numb) {  // Reusable timer
    -    thetimer = setTimeout("imgturn('" +numb+ "')", 1000);
    -}
    -function imgturn(numb) {
    -    if (document.images) {
    -        if (numb == "4") {
    -            document["demo"].src = eval("demo4.src");
    -            timeimgs('1');
    -        }
    -    else {
    -        document["demo"].src = eval("demo" + numb + ".src");
    -        timeimgs(numb = ++numb);
    -        }
    -    }
    -}
    -// -->
    -</script>
    -</head>
    -<body onload="timeimgs('1');">
    -<div align="center">
    -    <img src="http://www.gstatic.com/webp/gallery/1.webp" name="demo" width="1024" height="768" alt="demo" title="PYTHON-BOTTLE DEMO">
    -</div>
    -</body>
    -</html>
    -"""
    -#
    -@route('/')
    -def index():
    -    return GALLERY
    -
    -# Ejemplo de uso de bottle.request para mostrar tu direccion ip
    -@route('/tu_ip') # ingresando a esa URL devuelve tu IP
    -def show_ip():
    -    ip = request.environ.get('REMOTE_ADDR')
    -    return ip
    -
    -# Ejemplo de uso de bottle.error para el 404, la pagina no existe
    -@error(404)
    -def mistake404(code): # Usando HTML directamente, de ejemplo.
    -    return '<title>bottle app</title><br><b>ERROR 404:la pagina no existe.</b>'
    -
    -# Ejemplo de uso de bottle.abort para URL no permitida, error 401
    -@route('/restricted')
    -def restricted():
    -    abort(401, 'ERROR 401:URL no permitida.')
    -
    -# Ejemplo de Redireccion bottle.redirect de URL, por URL incorrecta
    -@route('/index.php') # si va a index.php
    -def wrong():
    -    redirect("/") # enviarlo a "/"
    -
    -###############################################################################
    -
    -# Ejecucion de Main
    -def main():
    -    debug(True)# True para desarrollo, False para Produccion
    -    #
    -    # Por que es esto?: Puerto <1024 requiere Privilegios elevados
    -    if os.geteuid()==0: # root check
    -        run(host='0.0.0.0', port=80, reloader=True)
    -    else:
    -        run(host='127.0.0.1', port=8080, reloader=True)
    -
    -if __name__=="__main__":
    -    main()
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +from bottle import route
    +from bottle import run
    +from bottle import redirect
    +from bottle import debug
    +from bottle import error
    +from bottle import request
    +from bottle import abort
    +import os
    +#
    +GALLERY = """
    +<!DOCTYPE HTML>
    +<html>
    +  <head>
    +    <title>PYTHON-BOTTLE DEMO</title>
    +    <link rel="shortcut icon" href="http://python.org.ar/images/pyar.ico" type="image/x-icon"/>
    +    <meta http-equiv="X-UA-Compatible" content="chrome=1">
    +    <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
    +    <style type="text/css"> body { background-color: black; } </style>
    +<script language="JavaScript">
    +<!--
    +if (document.images) {
    +    demo1 = new Image();
    +    demo1.src = "http://www.gstatic.com/webp/gallery/5.webp";
    +    demo2 = new Image();
    +    demo2.src = "http://www.gstatic.com/webp/gallery/2.webp";
    +    demo3 = new Image();
    +    demo3.src = "http://www.gstatic.com/webp/gallery/3.webp";
    +    demo4 = new Image();
    +    demo4.src = "http://www.gstatic.com/webp/gallery/4.webp";
    +}
    +function timeimgs(numb) {  // Reusable timer
    +    thetimer = setTimeout("imgturn('" +numb+ "')", 1000);
    +}
    +function imgturn(numb) {
    +    if (document.images) {
    +        if (numb == "4") {
    +            document["demo"].src = eval("demo4.src");
    +            timeimgs('1');
    +        }
    +    else {
    +        document["demo"].src = eval("demo" + numb + ".src");
    +        timeimgs(numb = ++numb);
    +        }
    +    }
    +}
    +// -->
    +</script>
    +</head>
    +<body onload="timeimgs('1');">
    +<div align="center">
    +    <img src="http://www.gstatic.com/webp/gallery/1.webp" name="demo" width="1024" height="768" alt="demo" title="PYTHON-BOTTLE DEMO">
    +</div>
    +</body>
    +</html>
    +"""
    +#
    +@route('/')
    +def index():
    +    return GALLERY
    +
    +# Ejemplo de uso de bottle.request para mostrar tu direccion ip
    +@route('/tu_ip') # ingresando a esa URL devuelve tu IP
    +def show_ip():
    +    ip = request.environ.get('REMOTE_ADDR')
    +    return ip
    +
    +# Ejemplo de uso de bottle.error para el 404, la pagina no existe
    +@error(404)
    +def mistake404(code): # Usando HTML directamente, de ejemplo.
    +    return '<title>bottle app</title><br><b>ERROR 404:la pagina no existe.</b>'
    +
    +# Ejemplo de uso de bottle.abort para URL no permitida, error 401
    +@route('/restricted')
    +def restricted():
    +    abort(401, 'ERROR 401:URL no permitida.')
    +
    +# Ejemplo de Redireccion bottle.redirect de URL, por URL incorrecta
    +@route('/index.php') # si va a index.php
    +def wrong():
    +    redirect("/") # enviarlo a "/"
    +
    +###############################################################################
    +
    +# Ejecucion de Main
    +def main():
    +    debug(True)# True para desarrollo, False para Produccion
    +    #
    +    # Por que es esto?: Puerto <1024 requiere Privilegios elevados
    +    if os.geteuid()==0: # root check
    +        run(host='0.0.0.0', port=80, reloader=True)
    +    else:
    +        run(host='127.0.0.1', port=8080, reloader=True)
    +
    +if __name__=="__main__":
    +    main()
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    Fe de Erratas: seguramente hay una forma mejor de hacerlo, pero esta funciona correctamente.

    diff --git a/recetario/bottle/holamundo/index.html b/recetario/bottle/holamundo/index.html index d28dd127a..e9ff4d071 100644 --- a/recetario/bottle/holamundo/index.html +++ b/recetario/bottle/holamundo/index.html @@ -35,7 +35,7 @@ Ejemplo: juan@"> - + Ir al contenido principal @@ -69,12 +69,12 @@ - +
    @@ -96,80 +96,80 @@

    Hola Mundo Bottle

    • Cómo hacer un hola mundo en Bottle, ejemplo simple.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -from bottle import route, run
    -@route('/')
    -def index():
    -    return 'Hola Mundo!'
    -run()
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +from bottle import route, run
    +@route('/')
    +def index():
    +    return 'Hola Mundo!'
    +run()
     

    Ejemplo:

    -
    juan@wind:~$ /usr/bin/env python holamundo.py
    -Bottle server starting up (using WSGIRefServer())...
    -Listening on http://127.0.0.1:8080/
    -Use Ctrl-C to quit.
    -
    -localhost.localdomain - - [18/Jul/2011 18:22:09] "GET / HTTP/1.1" 200 11
    -localhost.localdomain - - [18/Jul/2011 18:22:09] "GET /favicon.ico HTTP/1.1" 404 687
    -^C
    -juan@wind:~$
    +
    juan@wind:~$ /usr/bin/env python holamundo.py
    +Bottle server starting up (using WSGIRefServer())...
    +Listening on http://127.0.0.1:8080/
    +Use Ctrl-C to quit.
    +
    +localhost.localdomain - - [18/Jul/2011 18:22:09] "GET / HTTP/1.1" 200 11
    +localhost.localdomain - - [18/Jul/2011 18:22:09] "GET /favicon.ico HTTP/1.1" 404 687
    +^C
    +juan@wind:~$
     

    • Mejorando nuestro hola mundo en Bottle, ejemplo más completo, ideal para Plantilla para una App nueva.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -from bottle import route
    -from bottle import run
    -from bottle import redirect
    -from bottle import debug
    -from bottle import error
    -from bottle import request
    -from bottle import abort
    -import os
    -#
    -@route('/')
    -def index():
    -    return 'Hola Mundo!'
    -
    -# Ejemplo de uso de bottle.request para mostrar tu direccion ip
    -@route('/tuip') # ingresando a esa URL devuelve tu IP
    -def show_ip():
    -    ip = request.environ.get('REMOTE_ADDR')
    -    return ip
    -
    -# Ejemplo de uso de bottle.error para el 404, la pagina no existe
    -@error(404)
    -def mistake404(code): # Usando HTML directamente, de ejemplo.
    -    return '<title>bottle app</title><br><b>ERROR 404:la pagina no existe.</b>'
    -
    -# Ejemplo de uso de bottle.abort para URL no permitida, error 401
    -@route('/restricted')
    -def restricted():
    -    abort(401, 'ERROR 401:URL no permitida.')
    -
    -# Ejemplo de Redireccion bottle.redirect de URL, por URL incorrecta
    -@route('/index.php') # si va a index.php
    -def wrong():
    -    redirect("/") # enviarlo a "/"
    -
    -###############################################################################
    -
    -# Ejecucion de Main
    -def main():
    -    debug(True)# True para desarrollo, False para Produccion
    -    #
    -    # Por que es esto?: Puerto <1024 requiere Privilegios elevados
    -    if os.geteuid()==0: # root check
    -        run(host='0.0.0.0', port=80, reloader=True)
    -    else:
    -        run(host='127.0.0.1', port=8080, reloader=True)
    -
    -if __name__=="__main__":
    -    main()
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +from bottle import route
    +from bottle import run
    +from bottle import redirect
    +from bottle import debug
    +from bottle import error
    +from bottle import request
    +from bottle import abort
    +import os
    +#
    +@route('/')
    +def index():
    +    return 'Hola Mundo!'
    +
    +# Ejemplo de uso de bottle.request para mostrar tu direccion ip
    +@route('/tuip') # ingresando a esa URL devuelve tu IP
    +def show_ip():
    +    ip = request.environ.get('REMOTE_ADDR')
    +    return ip
    +
    +# Ejemplo de uso de bottle.error para el 404, la pagina no existe
    +@error(404)
    +def mistake404(code): # Usando HTML directamente, de ejemplo.
    +    return '<title>bottle app</title><br><b>ERROR 404:la pagina no existe.</b>'
    +
    +# Ejemplo de uso de bottle.abort para URL no permitida, error 401
    +@route('/restricted')
    +def restricted():
    +    abort(401, 'ERROR 401:URL no permitida.')
    +
    +# Ejemplo de Redireccion bottle.redirect de URL, por URL incorrecta
    +@route('/index.php') # si va a index.php
    +def wrong():
    +    redirect("/") # enviarlo a "/"
    +
    +###############################################################################
    +
    +# Ejecucion de Main
    +def main():
    +    debug(True)# True para desarrollo, False para Produccion
    +    #
    +    # Por que es esto?: Puerto <1024 requiere Privilegios elevados
    +    if os.geteuid()==0: # root check
    +        run(host='0.0.0.0', port=80, reloader=True)
    +    else:
    +        run(host='127.0.0.1', port=8080, reloader=True)
    +
    +if __name__=="__main__":
    +    main()
     

    Nota: Hay más Features en Bottle_*, pero eso es suficiente para un Hola Mundo completo y didáctico.*

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    diff --git a/recetario/calculardigitoverificadormodulodiez/index.html b/recetario/calculardigitoverificadormodulodiez/index.html index d9dde1d1a..c48949fac 100644 --- a/recetario/calculardigitoverificadormodulodiez/index.html +++ b/recetario/calculardigitoverificadormodulodiez/index.html @@ -26,7 +26,7 @@ digito_verificador_modulo10 es una función a la que se le pasa un código (ej. cadena '01234567890') y devuelve el dígito verificador a agregar correspondiente a la verificación módulo 10. "> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -89,31 +89,31 @@

    Cálculo De Dígito Verificador Módulo 10

    Esta verificación se usa en códigos de barra, por ej. en las facturas en el sistema impositivo argentino, donde se consigna el CUIT del emisor, CAI/CAE, número de factura, etc.

    Para más información, ver Resolución General 1702 de la AFIP.

    Ejemplo:

    -
    >>> digito_verificador_modulo10("01234567890")
    -'5'
    ->>> digito_verificador_modulo10('111111111112233334444444444444455555555')
    -'3'
    ->>> digito_verificador_modulo10('123456789012345678901234567890123456789')
    -'0'
    +
    >>> digito_verificador_modulo10("01234567890")
    +'5'
    +>>> digito_verificador_modulo10('111111111112233334444444444444455555555')
    +'3'
    +>>> digito_verificador_modulo10('123456789012345678901234567890123456789')
    +'0'
     

    Código:

    -
    def digito_verificador_modulo10(codigo):
    -    "Rutina para el cálculo del dígito verificador 'módulo 10'"
    -    # Ver RG 1702 AFIP
    -    # Etapa 1: comenzar desde la izquierda, sumar todos los caracteres ubicados en las posiciones impares.
    -    etapa1 = sum([int(c) for i,c in enumerate(codigo) if not i%2])
    -    # Etapa 2: multiplicar la suma obtenida en la etapa 1 por el número 3
    -    etapa2 = etapa1 * 3
    -    # Etapa 3: comenzar desde la izquierda, sumar todos los caracteres que están ubicados en las posiciones pares.
    -    etapa3 = sum([int(c) for i,c in enumerate(codigo) if i%2])
    -    # Etapa 4: sumar los resultados obtenidos en las etapas 2 y 3.
    -    etapa4 = etapa2 + etapa3
    -    # Etapa 5: buscar el menor número que sumado al resultado obtenido en la etapa 4 dé un número múltiplo de 10.
    -    # Este será el valor del dígito verificador del módulo 10.
    -    digito = 10 - (etapa4 - (int(etapa4 / 10) * 10))
    -    if digito == 10:
    -        digito = 0
    -    return str(digito)
    +
    def digito_verificador_modulo10(codigo):
    +    "Rutina para el cálculo del dígito verificador 'módulo 10'"
    +    # Ver RG 1702 AFIP
    +    # Etapa 1: comenzar desde la izquierda, sumar todos los caracteres ubicados en las posiciones impares.
    +    etapa1 = sum([int(c) for i,c in enumerate(codigo) if not i%2])
    +    # Etapa 2: multiplicar la suma obtenida en la etapa 1 por el número 3
    +    etapa2 = etapa1 * 3
    +    # Etapa 3: comenzar desde la izquierda, sumar todos los caracteres que están ubicados en las posiciones pares.
    +    etapa3 = sum([int(c) for i,c in enumerate(codigo) if i%2])
    +    # Etapa 4: sumar los resultados obtenidos en las etapas 2 y 3.
    +    etapa4 = etapa2 + etapa3
    +    # Etapa 5: buscar el menor número que sumado al resultado obtenido en la etapa 4 dé un número múltiplo de 10.
    +    # Este será el valor del dígito verificador del módulo 10.
    +    digito = 10 - (etapa4 - (int(etapa4 / 10) * 10))
    +    if digito == 10:
    +        digito = 0
    +    return str(digito)
     

    Autor / Autores:

    MarianoReingart

    diff --git a/recetario/checkdistroversion/index.html b/recetario/checkdistroversion/index.html index 65b75a983..369533c9f 100644 --- a/recetario/checkdistroversion/index.html +++ b/recetario/checkdistroversion/index.html @@ -30,7 +30,7 @@ if"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - +
    @@ -89,17 +89,17 @@

    Check Distro Version

    Chequea la versión de la Distribución Linux, y actúa en función de eso. Utiliza el módulo platform

    -
    import platform
    -
    -osInfo = ('Ubuntu', '10.10', 'maverick')
    -sysInfo = platform.linux_distribution()
    -
    -if osInfo == sysInfo:
    -    print(" OK ")
    -    # Aca va que hacer si esta OK
    -else:
    -    print(" ERROR ")
    -    # Aca va que hacer si la version no es correcta
    +
    import platform
    +
    +osInfo = ('Ubuntu', '10.10', 'maverick')
    +sysInfo = platform.linux_distribution()
    +
    +if osInfo == sysInfo:
    +    print(" OK ")
    +    # Aca va que hacer si esta OK
    +else:
    +    print(" ERROR ")
    +    # Aca va que hacer si la version no es correcta
     
    diff --git a/recetario/chequearinterfacesinternetlinux/index.html b/recetario/chequearinterfacesinternetlinux/index.html index 7ae2e5b90..2e36e0763 100644 --- a/recetario/chequearinterfacesinternetlinux/index.html +++ b/recetario/chequearinterfacesinternetlinux/index.html @@ -31,7 +31,7 @@ ''' Lis"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - +
    @@ -90,292 +90,292 @@

    Chequear Interfaces Internet Linux

    Si te esta pasando que necesitas saber ¿en qué placa de red tenés internet en Gnu/Linux con Python ? Bueno, por ahí esto te sirve 🙂

    -
    import socket
    -
    -DEBUG = True
    -
    -def list_net_devices():
    -    '''
    -    Lista todas las placas de red.
    -        Retorna:
    -            Lista con diccionarios, cada diccionario de la lista tiene
    -            como key el nombre de la iface asignada y los valores del
    -            diccionario son los datos correspondiente a la interfaz de red
    -    '''
    -    fh = open('/proc/net/dev', 'r')
    -    lines = fh.readlines()
    -    fh.close()
    -
    -    ifaces = []
    -    for line in lines:
    -        if ':' in line:
    -            iface_name, iface_data = line.split(':')
    -            new_iface = {}
    -            # limpiamos iface_data ...
    -            data = []
    -            for item in iface_data.strip().split(' '):
    -                if item != '':
    -                    data.append(item)
    -            new_iface[iface_name.strip()] = data
    -            ifaces.append(new_iface)
    -
    -    return ifaces
    -
    -def info_net_device(device):
    -    '''
    -    Devuelve informacion de un dispositivo de red en particular
    -        Argumentos:
    -            device(str)
    -        Retorna:
    -            Diccionario siendo la clave el device solicitado y
    -            los datos como values.
    -            None en caso de no encontrarse el dispositivo de red.
    -        Funciones:
    -            list_net_devices
    -    '''
    -    if not isinstance(device, str):
    -        raise Exception, 'el device debe ser un string, obtuve %s' % repr(device)
    -
    -    devices = list_net_devices()
    -    info_iface = {}
    -    for iface in devices:
    -        kw = iface.keys().pop()
    -        if kw == device:
    -            info_iface[kw] = iface[kw]
    -            return info_iface
    -    return None
    -
    -def route_net_devices():
    -    '''
    -    Devuelve las rutas asignadas a los dispositivos de red
    -        Retorna:
    -            Diccionario siendo la clave el dispositivo de red y su
    -            value la ip de la ruta por defecto como string.
    -    '''
    -    fh = open('/proc/net/route', 'r')
    -    lines = fh.readlines()
    -    fh.close()
    -    devices = {}
    -
    -    for line in lines:
    -        if line.split('\t')[0] != 'Iface':
    -            iface = line.split('\t')[0]
    -            hexgw = line.split('\t')[2]
    -            gw = '%s.%s.%s.%s' % (int(hexgw[6:8], 16),
    -                                  int(hexgw[4:6], 16),
    -                                  int(hexgw[2:4], 16),
    -                                  int(hexgw[:2], 16),
    -                                  )
    -            devices[iface] = gw
    -    return devices
    -
    -def ip_port_open(ip,port):
    -    '''
    -    Chequea si un puerto en una ip dada se encuentra abierto o no.
    -        Argumentos:
    -            ip(str)
    -            port(int)
    -        Retorna:
    -            True(bool), si el puerto en la ip dada esta abierto
    -            False(bool), si el puerto en la ip dada no esta abierto
    -    '''
    -    if not isinstance(ip, str):
    -        raise Exception, 'la ip debe ser un string, obtuve %s' % repr(ip)
    -    if not isinstance(port, int):
    -        raise Exception, 'el puerto debe ser un int, obtuve %s' % repr(port)
    -
    -    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    -    try:
    -        s.connect((ip, int(port)))
    -        s.shutdown(2)
    -        return True
    -    except:
    -        return False
    -
    -def host_port_open(hostname, port):
    -    '''
    -    Chequea si un puerto en un host dado se encuentra abierto o no.
    -        Argumentos:
    -            hostname(str)
    -            port(int)
    -        Retorna:
    -            True(bool), si el puerto en el hostname dado esta abierto
    -            False(bool), si el puerto en el hostname dado no esta abierto
    -        Funciones:
    -            ip_port_open
    -    '''
    -    if not isinstance(hostname, str):
    -        raise Exception, 'el hostname debe ser un string, obtuve %s' % repr(hostname)
    -    if not isinstance(port, int):
    -        raise Exception, 'el puerto debe ser un int, obtuve %s' % repr(port)
    -
    -    ip = socket.gethostbyname(hostname)
    -    return ip_port_open(ip, port)
    -
    -def dns_working(domain):
    -    '''
    -    Chequea si podemos resolver un dominio, por lo tanto, si funcionan los DNS
    -    Argumentos:
    -        domain(str)
    -    Retorna:
    -        True(bool) en caso de poder resolver el dominio
    -        False(bool) en caso de no poder resolver el dominio
    -    '''
    -    if not isinstance(domain, str):
    -        raise Exception, 'el domain debe ser un string'
    -
    -    try:
    -        socket.gethostbyname(domain)
    -        return True
    -    except Exception:
    -        return False
    -
    -def gateway_recheable(dest_addr=None, inet=None):
    -    '''
    -    Chequea si tenemos conexion contra el gateway pasado como parametro.
    -    Si el gateway bloquea los paquetes icmp, este metodo no funciona.
    -        Argumentos:
    -            gateway(str)
    -        Retorna:
    -            True(bool) si el gateway es recheable
    -            False(bool) si el gateways no es recheable
    -    '''
    -
    -    if not isinstance(dest_addr, str):
    -        raise Exception, 'gateway debe ser una ip como string'
    -
    -    def create_sockets(ttl):
    -        """
    -        Sockets necesarios para el traceroute, enviamos por udp y
    -        recibimos por icmp. Al usar icmp, precisamos permisos de super
    -        administrador.
    -            Argumentos:
    -                ttl(int) TimeToLive, campo que se setea en el paquete
    -                y cual se decrementa en 1 a medida que pasa por cada
    -                host / router
    -            Retorna:
    -                recv_socket, socket icmp en el que se escuchan datos
    -                send_socket, socket udp por el cual se envian datos
    -            Funciones:
    -                dns_working
    -        """
    -        icmp = socket.getprotobyname('icmp')
    -        udp = socket.getprotobyname('udp')
    -        timeout = 2
    -
    -        recv_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
    -        recv_socket.settimeout(timeout)
    -        send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, udp)
    -        send_socket.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
    -        return recv_socket, send_socket
    -
    -    ttl = 1
    -    port = 33434
    -    recheable = False
    -    remote_host = 'google.com'    # host usado para comprobar internet
    -
    -    try:
    -        if dest_addr is not None:
    -            recv_socket, send_socket = create_sockets(ttl)
    -            recv_socket.bind(("", port))
    -            send_socket.sendto("", (dest_addr, port))
    -            _, curr_addr = recv_socket.recvfrom(512)
    -            curr_addr = curr_addr[0]
    -            send_socket.close()
    -            recv_socket.close()
    -            if curr_addr == dest_addr:
    -                recheable = True
    -
    -        if inet is True:
    -            max_hops = 30
    -            max_hops_failures = 20
    -            failures = 0
    -            accerted_hops = 0
    -
    -            if not dns_working(remote_host):
    -                return False
    -            dest_addr = socket.gethostbyname(remote_host)
    -
    -            while True:
    -                recv_socket, send_socket = create_sockets(ttl)
    -                recv_socket.bind(("", port))
    -                send_socket.sendto("", (remote_host, port))
    -                try:
    -                    _, curr_addr = recv_socket.recvfrom(512)
    -                    curr_addr = curr_addr[0]
    -                    if curr_addr is not None:
    -                        accerted_hops += 1
    -                        if curr_addr == dest_addr:
    -                            recheable = True
    -                            send_socket.close()
    -                            recv_socket.close()
    -                            break
    -                    else:
    -                        failures += 1
    -
    -                except Exception, ex:
    -                    failures += 1
    -
    -                if DEBUG:
    -                    print 'ttl: %s chost: %s rhost: %s failures: %s accerts: %s' % (ttl,
    -                                                                                    curr_addr,
    -                                                                                    dest_addr,
    -                                                                                    failures,
    -                                                                                    accerted_hops)
    -
    -                ttl += 1
    -                send_socket.close()
    -                recv_socket.close()
    -
    -                if failures >= max_hops_failures:
    -                    recheable = False
    -                    break
    -
    -    except Exception, ex:
    -        recheable = False
    -
    -    return recheable
    +
    import socket
    +
    +DEBUG = True
    +
    +def list_net_devices():
    +    '''
    +    Lista todas las placas de red.
    +        Retorna:
    +            Lista con diccionarios, cada diccionario de la lista tiene
    +            como key el nombre de la iface asignada y los valores del
    +            diccionario son los datos correspondiente a la interfaz de red
    +    '''
    +    fh = open('/proc/net/dev', 'r')
    +    lines = fh.readlines()
    +    fh.close()
    +
    +    ifaces = []
    +    for line in lines:
    +        if ':' in line:
    +            iface_name, iface_data = line.split(':')
    +            new_iface = {}
    +            # limpiamos iface_data ...
    +            data = []
    +            for item in iface_data.strip().split(' '):
    +                if item != '':
    +                    data.append(item)
    +            new_iface[iface_name.strip()] = data
    +            ifaces.append(new_iface)
    +
    +    return ifaces
    +
    +def info_net_device(device):
    +    '''
    +    Devuelve informacion de un dispositivo de red en particular
    +        Argumentos:
    +            device(str)
    +        Retorna:
    +            Diccionario siendo la clave el device solicitado y
    +            los datos como values.
    +            None en caso de no encontrarse el dispositivo de red.
    +        Funciones:
    +            list_net_devices
    +    '''
    +    if not isinstance(device, str):
    +        raise Exception, 'el device debe ser un string, obtuve %s' % repr(device)
    +
    +    devices = list_net_devices()
    +    info_iface = {}
    +    for iface in devices:
    +        kw = iface.keys().pop()
    +        if kw == device:
    +            info_iface[kw] = iface[kw]
    +            return info_iface
    +    return None
    +
    +def route_net_devices():
    +    '''
    +    Devuelve las rutas asignadas a los dispositivos de red
    +        Retorna:
    +            Diccionario siendo la clave el dispositivo de red y su
    +            value la ip de la ruta por defecto como string.
    +    '''
    +    fh = open('/proc/net/route', 'r')
    +    lines = fh.readlines()
    +    fh.close()
    +    devices = {}
    +
    +    for line in lines:
    +        if line.split('\t')[0] != 'Iface':
    +            iface = line.split('\t')[0]
    +            hexgw = line.split('\t')[2]
    +            gw = '%s.%s.%s.%s' % (int(hexgw[6:8], 16),
    +                                  int(hexgw[4:6], 16),
    +                                  int(hexgw[2:4], 16),
    +                                  int(hexgw[:2], 16),
    +                                  )
    +            devices[iface] = gw
    +    return devices
    +
    +def ip_port_open(ip,port):
    +    '''
    +    Chequea si un puerto en una ip dada se encuentra abierto o no.
    +        Argumentos:
    +            ip(str)
    +            port(int)
    +        Retorna:
    +            True(bool), si el puerto en la ip dada esta abierto
    +            False(bool), si el puerto en la ip dada no esta abierto
    +    '''
    +    if not isinstance(ip, str):
    +        raise Exception, 'la ip debe ser un string, obtuve %s' % repr(ip)
    +    if not isinstance(port, int):
    +        raise Exception, 'el puerto debe ser un int, obtuve %s' % repr(port)
    +
    +    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    +    try:
    +        s.connect((ip, int(port)))
    +        s.shutdown(2)
    +        return True
    +    except:
    +        return False
    +
    +def host_port_open(hostname, port):
    +    '''
    +    Chequea si un puerto en un host dado se encuentra abierto o no.
    +        Argumentos:
    +            hostname(str)
    +            port(int)
    +        Retorna:
    +            True(bool), si el puerto en el hostname dado esta abierto
    +            False(bool), si el puerto en el hostname dado no esta abierto
    +        Funciones:
    +            ip_port_open
    +    '''
    +    if not isinstance(hostname, str):
    +        raise Exception, 'el hostname debe ser un string, obtuve %s' % repr(hostname)
    +    if not isinstance(port, int):
    +        raise Exception, 'el puerto debe ser un int, obtuve %s' % repr(port)
    +
    +    ip = socket.gethostbyname(hostname)
    +    return ip_port_open(ip, port)
    +
    +def dns_working(domain):
    +    '''
    +    Chequea si podemos resolver un dominio, por lo tanto, si funcionan los DNS
    +    Argumentos:
    +        domain(str)
    +    Retorna:
    +        True(bool) en caso de poder resolver el dominio
    +        False(bool) en caso de no poder resolver el dominio
    +    '''
    +    if not isinstance(domain, str):
    +        raise Exception, 'el domain debe ser un string'
    +
    +    try:
    +        socket.gethostbyname(domain)
    +        return True
    +    except Exception:
    +        return False
    +
    +def gateway_recheable(dest_addr=None, inet=None):
    +    '''
    +    Chequea si tenemos conexion contra el gateway pasado como parametro.
    +    Si el gateway bloquea los paquetes icmp, este metodo no funciona.
    +        Argumentos:
    +            gateway(str)
    +        Retorna:
    +            True(bool) si el gateway es recheable
    +            False(bool) si el gateways no es recheable
    +    '''
    +
    +    if not isinstance(dest_addr, str):
    +        raise Exception, 'gateway debe ser una ip como string'
    +
    +    def create_sockets(ttl):
    +        """
    +        Sockets necesarios para el traceroute, enviamos por udp y
    +        recibimos por icmp. Al usar icmp, precisamos permisos de super
    +        administrador.
    +            Argumentos:
    +                ttl(int) TimeToLive, campo que se setea en el paquete
    +                y cual se decrementa en 1 a medida que pasa por cada
    +                host / router
    +            Retorna:
    +                recv_socket, socket icmp en el que se escuchan datos
    +                send_socket, socket udp por el cual se envian datos
    +            Funciones:
    +                dns_working
    +        """
    +        icmp = socket.getprotobyname('icmp')
    +        udp = socket.getprotobyname('udp')
    +        timeout = 2
    +
    +        recv_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
    +        recv_socket.settimeout(timeout)
    +        send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, udp)
    +        send_socket.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
    +        return recv_socket, send_socket
    +
    +    ttl = 1
    +    port = 33434
    +    recheable = False
    +    remote_host = 'google.com'    # host usado para comprobar internet
    +
    +    try:
    +        if dest_addr is not None:
    +            recv_socket, send_socket = create_sockets(ttl)
    +            recv_socket.bind(("", port))
    +            send_socket.sendto("", (dest_addr, port))
    +            _, curr_addr = recv_socket.recvfrom(512)
    +            curr_addr = curr_addr[0]
    +            send_socket.close()
    +            recv_socket.close()
    +            if curr_addr == dest_addr:
    +                recheable = True
    +
    +        if inet is True:
    +            max_hops = 30
    +            max_hops_failures = 20
    +            failures = 0
    +            accerted_hops = 0
    +
    +            if not dns_working(remote_host):
    +                return False
    +            dest_addr = socket.gethostbyname(remote_host)
    +
    +            while True:
    +                recv_socket, send_socket = create_sockets(ttl)
    +                recv_socket.bind(("", port))
    +                send_socket.sendto("", (remote_host, port))
    +                try:
    +                    _, curr_addr = recv_socket.recvfrom(512)
    +                    curr_addr = curr_addr[0]
    +                    if curr_addr is not None:
    +                        accerted_hops += 1
    +                        if curr_addr == dest_addr:
    +                            recheable = True
    +                            send_socket.close()
    +                            recv_socket.close()
    +                            break
    +                    else:
    +                        failures += 1
    +
    +                except Exception, ex:
    +                    failures += 1
    +
    +                if DEBUG:
    +                    print 'ttl: %s chost: %s rhost: %s failures: %s accerts: %s' % (ttl,
    +                                                                                    curr_addr,
    +                                                                                    dest_addr,
    +                                                                                    failures,
    +                                                                                    accerted_hops)
    +
    +                ttl += 1
    +                send_socket.close()
    +                recv_socket.close()
    +
    +                if failures >= max_hops_failures:
    +                    recheable = False
    +                    break
    +
    +    except Exception, ex:
    +        recheable = False
    +
    +    return recheable
     

    Ejemplitos de cómo se usa:

    -
    In [8]: # chequeamos conexion contra la db
    -
    -In [9]: host_port_open('gondor.airtrack.ovz', 3306)
    -Out[9]: True
    -
    -In [10]: # http de googl ...
    -
    -In [11]: host_port_open('www.google.com', 80)
    -Out[11]: True
    -
    -In [12]: host_port_open('www.google.com', 81)
    -Out[12]: False
    -
    -In [15]: # pedimos el gateway de la eth1 ...
    -
    -In [16]: route_net_devices()
    -Out[16]: {'eth1': '192.168.1.1', 'eth2': '0.0.0.0', 'lo': '0.0.0.0'}
    -
    -In [17]: # aha ... ahora veamos si tenemos conexion contra ese gw ...
    -
    -In [18]: gateway_recheable(route_net_devices()['eth1'])
    -Out[18]: True
    -
    -In [19]: # y nos da internet ese gw ? ...
    -
    -In [20]: gateway_recheable(route_net_devices()['eth1'], inet=True)
    -ttl: 1 chost: 192.168.1.1 rhost: 209.85.195.104 failures: 0 accerts: 1
    -ttl: 2 chost: 192.168.1.1 rhost: 209.85.195.104 failures: 1 accerts: 1
    -ttl: 3 chost: 192.168.1.1 rhost: 209.85.195.104 failures: 2 accerts: 1
    -ttl: 4 chost: 192.168.1.1 rhost: 209.85.195.104 failures: 3 accerts: 1
    -ttl: 5 chost: 192.168.1.1 rhost: 209.85.195.104 failures: 4 accerts: 1
    -ttl: 6 chost: 200.89.165.213 rhost: 209.85.195.104 failures: 4 accerts: 2
    -ttl: 7 chost: 200.89.165.194 rhost: 209.85.195.104 failures: 4 accerts: 3
    -ttl: 8 chost: 200.89.165.194 rhost: 209.85.195.104 failures: 5 accerts: 3
    -ttl: 9 chost: 200.89.165.194 rhost: 209.85.195.104 failures: 6 accerts: 3
    -ttl: 10 chost: 200.49.159.254 rhost: 209.85.195.104 failures: 6 accerts: 4
    -ttl: 11 chost: 209.85.251.28 rhost: 209.85.195.104 failures: 6 accerts: 5
    -ttl: 12 chost: 209.85.251.6 rhost: 209.85.195.104 failures: 6 accerts: 6
    -Out[20]: True
    +
    In [8]: # chequeamos conexion contra la db
    +
    +In [9]: host_port_open('gondor.airtrack.ovz', 3306)
    +Out[9]: True
    +
    +In [10]: # http de googl ...
    +
    +In [11]: host_port_open('www.google.com', 80)
    +Out[11]: True
    +
    +In [12]: host_port_open('www.google.com', 81)
    +Out[12]: False
    +
    +In [15]: # pedimos el gateway de la eth1 ...
    +
    +In [16]: route_net_devices()
    +Out[16]: {'eth1': '192.168.1.1', 'eth2': '0.0.0.0', 'lo': '0.0.0.0'}
    +
    +In [17]: # aha ... ahora veamos si tenemos conexion contra ese gw ...
    +
    +In [18]: gateway_recheable(route_net_devices()['eth1'])
    +Out[18]: True
    +
    +In [19]: # y nos da internet ese gw ? ...
    +
    +In [20]: gateway_recheable(route_net_devices()['eth1'], inet=True)
    +ttl: 1 chost: 192.168.1.1 rhost: 209.85.195.104 failures: 0 accerts: 1
    +ttl: 2 chost: 192.168.1.1 rhost: 209.85.195.104 failures: 1 accerts: 1
    +ttl: 3 chost: 192.168.1.1 rhost: 209.85.195.104 failures: 2 accerts: 1
    +ttl: 4 chost: 192.168.1.1 rhost: 209.85.195.104 failures: 3 accerts: 1
    +ttl: 5 chost: 192.168.1.1 rhost: 209.85.195.104 failures: 4 accerts: 1
    +ttl: 6 chost: 200.89.165.213 rhost: 209.85.195.104 failures: 4 accerts: 2
    +ttl: 7 chost: 200.89.165.194 rhost: 209.85.195.104 failures: 4 accerts: 3
    +ttl: 8 chost: 200.89.165.194 rhost: 209.85.195.104 failures: 5 accerts: 3
    +ttl: 9 chost: 200.89.165.194 rhost: 209.85.195.104 failures: 6 accerts: 3
    +ttl: 10 chost: 200.49.159.254 rhost: 209.85.195.104 failures: 6 accerts: 4
    +ttl: 11 chost: 209.85.251.28 rhost: 209.85.195.104 failures: 6 accerts: 5
    +ttl: 12 chost: 209.85.251.6 rhost: 209.85.195.104 failures: 6 accerts: 6
    +Out[20]: True
     
    diff --git a/recetario/chequeo_de_paquetes_apt_linux/index.html b/recetario/chequeo_de_paquetes_apt_linux/index.html index 77b5b95c7..41343d8b5 100644 --- a/recetario/chequeo_de_paquetes_apt_linux/index.html +++ b/recetario/chequeo_de_paquetes_apt_linux/index.html @@ -31,7 +31,7 @@ # cache = apt.C"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - +
    @@ -92,33 +92,33 @@

    Chequeo De Paquetes Con Apt

    • Cómo saber si un paquete está instalado, o no, y si el mismo existe usando Python. Se muestra un ejemplo interactivo simple.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -import apt
    -#
    -cache = apt.Cache()
    -cache.open()
    -program = raw_input(' Cual es el nombre del programa?: ')
    -if program in cache:
    -    if cache[program].is_installed:
    -        print (' El programa esta instalado!\n')
    -    else:
    -        print (' El programa no esta instalado!\n')
    -else:
    -    print (' Estas seguro del Nombre del programa?, el programa no existe!\n')
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +import apt
    +#
    +cache = apt.Cache()
    +cache.open()
    +program = raw_input(' Cual es el nombre del programa?: ')
    +if program in cache:
    +    if cache[program].is_installed:
    +        print (' El programa esta instalado!\n')
    +    else:
    +        print (' El programa no esta instalado!\n')
    +else:
    +    print (' Estas seguro del Nombre del programa?, el programa no existe!\n')
     

    Ejemplo:

    -
    juan@wind:~$ /usr/bin/env python apt-app-check.py
    - Cual es el nombre del programa?: python
    - El programa esta instalado!
    -juan@wind:~$ /usr/bin/env python apt-app-check.py
    - Cual es el nombre del programa?: monodevelop
    - El programa no esta instalado!
    -juan@wind:~$ /usr/bin/env python apt-app-check.py
    - Cual es el nombre del programa?: hjklsdajflkdshjdskabnv
    - Estas seguro del Nombre del programa?, el programa no existe!
    -juan@wind:~$
    +
    juan@wind:~$ /usr/bin/env python apt-app-check.py
    + Cual es el nombre del programa?: python
    + El programa esta instalado!
    +juan@wind:~$ /usr/bin/env python apt-app-check.py
    + Cual es el nombre del programa?: monodevelop
    + El programa no esta instalado!
    +juan@wind:~$ /usr/bin/env python apt-app-check.py
    + Cual es el nombre del programa?: hjklsdajflkdshjdskabnv
    + Estas seguro del Nombre del programa?, el programa no existe!
    +juan@wind:~$
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    Fe de Erratas: seguramente hay una forma mejor de hacerlo, pero esta funciona correctamente.

    diff --git a/recetario/comobajartodoslosbuffersaldisco/index.html b/recetario/comobajartodoslosbuffersaldisco/index.html index 62d35cac5..1ca38f558 100644 --- a/recetario/comobajartodoslosbuffersaldisco/index.html +++ b/recetario/comobajartodoslosbuffersaldisco/index.html @@ -28,7 +28,7 @@ Cerrar correctamente tu programa Mejores Prácticas (o Best Practice) de cómo debería cerrarse tu programa de una manera linux-friendly, para p"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    @@ -92,22 +92,22 @@

    Comobajartodoslosbuffersaldisco

    Cerrar correctamente tu programa

    Mejores Prácticas (o Best Practice) de cómo debería cerrarse tu programa de una manera linux-friendly, para prevenir corrupción/pérdida de datos.

    Disclaimer: Esto es más relacionado al OS que a Python en si, válido para los SO tipo Unix, pero es importante para lograr una aplicacion que funcione como debe.

    -
      import os
    -
    -  # Tu programa debe invocar este comando y luego cerrarse.
    -  os.system('sync')
    -
    -**¿Por qué?:**  En Linux los datos que teóricamente deberían estar escritos en el disco, no siempre lo estan en la realidad, por un período de tiempo variable de unos segundos podrían mantenerse en RAM. El tiempo en segundos varía según las configuraciones del Kernel.
    +
      import os
    +
    +  # Tu programa debe invocar este comando y luego cerrarse.
    +  os.system('sync')
    +
    +**¿Por qué?:**  En Linux los datos que teóricamente deberían estar escritos en el disco, no siempre lo estan en la realidad, por un período de tiempo variable de unos segundos podrían mantenerse en RAM. El tiempo en segundos varía según las configuraciones del Kernel.
     

    Ejemplo:

    -
    cat /proc/sys/vm/dirty_writeback_centisecs
    -500
    +
    cat /proc/sys/vm/dirty_writeback_centisecs
    +500
     

    Esto significa que ningun dato se escribirá a disco realmente durante 5 Segundos, esto parece poco, pero en algunos casos como Notebooks o equipos con UPS este valor puede estar en 1500, es decir 15 segundos (lo que es un montón en Infomática). No piensen que este valor se puede reducir, esto tendría al Kernel contantemente escribiendo la RAM al disco. Esto es más notable en EXT4 con Extents activados. Alternativamente al ejemplo puedes agregar que detecte que OS es y ejecutar o no sync, también puede solucionar algunos "Segmentation Fault" misteriosos al cerrar tu programa.

    En mi Notebook, obtengo este resultado:

    (Si escribo un programa que no invoca a sync puedo perder 10 segundos de datos).

    -
    juan@wind:~$ cat /proc/sys/vm/dirty_writeback_centisecs
    -1000
    +
    juan@wind:~$ cat /proc/sys/vm/dirty_writeback_centisecs
    +1000
     
    diff --git a/recetario/comolevantarunservidorhttpmultithread/index.html b/recetario/comolevantarunservidorhttpmultithread/index.html index 32e5b1bf2..d7e42aa44 100644 --- a/recetario/comolevantarunservidorhttpmultithread/index.html +++ b/recetario/comolevantarunservidorhttpmultithread/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +
    @@ -85,15 +85,15 @@

    Como Levantar Un Servidor Http Multithread

    Este ejemplo muestra cómo levantar un servidor web en Python sirviendo el contenido del directorio actual utilizando threads para manejar las solicitudes.

    Para usarlo, simplemente hay que llamar a este módulo desde la línea de comando, si se llamara test.py entonces correr "python test.py"

    -
    import SocketServer
    -import BaseHTTPServer
    -import SimpleHTTPServer
    -
    -class Server(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
    -    pass
    -
    -if __name__ == '__main__':
    -    SimpleHTTPServer.test(ServerClass=Server)
    +
    import SocketServer
    +import BaseHTTPServer
    +import SimpleHTTPServer
    +
    +class Server(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
    +    pass
    +
    +if __name__ == '__main__':
    +    SimpleHTTPServer.test(ServerClass=Server)
     
    diff --git a/recetario/comolevantarunservidorhttpsimple/index.html b/recetario/comolevantarunservidorhttpsimple/index.html index 9b2dff47d..6aadf84c7 100644 --- a/recetario/comolevantarunservidorhttpsimple/index.html +++ b/recetario/comolevantarunservidorhttpsimple/index.html @@ -29,7 +29,7 @@ o simplemente desde consola: python -m Simp"> - +Ir al contenido principal @@ -63,12 +63,12 @@ - + @@ -88,11 +88,11 @@

    Como Levantar Un Servidor Http Simple

    Este ejemplo muestra cómo levantar un servidor http en Python que sirva el contenido del directorio actual.

    -
    import SimpleHTTPServer
    -SimpleHTTPServer.test()
    +
    import SimpleHTTPServer
    +SimpleHTTPServer.test()
     

    o simplemente desde consola:

    -
    python -m SimpleHTTPServer
    +
    python -m SimpleHTTPServer
     
    diff --git a/recetario/comunicarthreadsconqueue/index.html b/recetario/comunicarthreadsconqueue/index.html index 4818e9451..08ab8aba1 100644 --- a/recetario/comunicarthreadsconqueue/index.html +++ b/recetario/comunicarthreadsconqueue/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    diff --git a/recetario/creandounnuevoproyectopython/index.html b/recetario/creandounnuevoproyectopython/index.html index 2c65b3fa9..abda40704 100644 --- a/recetario/creandounnuevoproyectopython/index.html +++ b/recetario/creandounnuevoproyectopython/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + @@ -93,52 +93,52 @@

    Creando Un Nuevo Proyecto Python

    1. Instalá pip

    -
    $ sudo curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python
    +
    $ sudo curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python
     
    1. Instalá virtualenwrapper y skeleton

    -
    $ sudo pip install virtualenwrapper
    -$ sudo pip install git+git://github.com/stumitchell/skeleton.git#egg=skeleton
    +
    $ sudo pip install virtualenwrapper
    +$ sudo pip install git+git://github.com/stumitchell/skeleton.git#egg=skeleton
     

    Notar que skeleton se está instalando desde un fork del proyecto original, que resuelve bugs de la versión original (aparentemente desmantenida)

    1. Configurá virtualenvwrapper.

    -
    $ mkdir ~/.virtualenvs           # acá se van a guardar tus entornos virtuales
    -$ mkdir ~/proyectos              # acá se van a guardar tus proyectos
    +
    $ mkdir ~/.virtualenvs           # acá se van a guardar tus entornos virtuales
    +$ mkdir ~/proyectos              # acá se van a guardar tus proyectos
     

    Luego editá tu ~/.bashrc agregando las siguientes líneas

    -
    WORKON_HOME=$HOME/.virtualenvs
    -PROJECT_HOME=$HOME/proyectos
    -
    -source /usr/local/bin/virtualenvwrapper.sh
    +
    WORKON_HOME=$HOME/.virtualenvs
    +PROJECT_HOME=$HOME/proyectos
    +
    +source /usr/local/bin/virtualenvwrapper.sh
     

    y recargá tus cambios

    -
    $ source ~/.bashrc
    +
    $ source ~/.bashrc
     
    1. Inicializá tu proyecto. Por ejemplo el proyecto zaraza

    -
    $ mkproject -t package zaraza
    +
    $ mkproject -t package zaraza
     

    Se te solicitarán algunos datos (nombre del proyecto, autor, licencia, etc.) y ¡(casi) listo! Estarás trabajando en tu proyecto zaraza. Tu prompt se verá así:

    -
    (zaraza)tin@morocha:~/proyectos/zaraza$
    +
    (zaraza)tin@morocha:~/proyectos/zaraza$
     

    ¿Qué sucedió? Se creó un directorio ~/proyectos/zaraza para tu proyecto, asociado a un virtualenv ubicado en ~/.virtualenvs /zaraza. skeleton automáticamente creó una estructura básica de paquete python ~/proyectos/zaraza/src incluyendo un setup.py basado en distribute.

    1. Instalá tu paquete en el virtualenv, para poder importarlo desde cualquier lado

    -
    (zaraza) $ cd  ~/proyectos/zaraza/src
    -(zaraza) $ pip install -e .
    +
    (zaraza) $ cd  ~/proyectos/zaraza/src
    +(zaraza) $ pip install -e .
     

    Esto agrega el directorio de desarrollo de tu proyecto al PYTHONPATH del virtualenv, de modo que puedes importar zaraza desde cualquier lado dentro del virtualenv (por ejemplo, cuando hagas una carpeta src/test al nivel de '/src/zaraza'

    ¿Y ahora?

    Cada vez que quieras trabajar en tu proyecto zaraza podes correr

    -
    $ workon zaraza
    +
    $ workon zaraza
     

    Para salir del virtualenv

    -
    (zaraza) $ deactivate
    +
    (zaraza) $ deactivate
     

    Algunos tips más a modo de despedida

    Virtualenwrapper es totalmente hookeable y extensible. Esta receta propone usar skeleton (que funciona como plugin de virtualenvwrapper.project) para crear una estructura de paquete estándar básica, pero hay plugins para proyectos más específicos. Por ejemplo virtualenwrapper.django

    diff --git a/recetario/crearejecutablewindows/index.html b/recetario/crearejecutablewindows/index.html index 577f5831b..988ded825 100644 --- a/recetario/crearejecutablewindows/index.html +++ b/recetario/crearejecutablewindows/index.html @@ -28,7 +28,7 @@ Crear un ejecutable (.EXE) nativo para Windows (que no requiera tener Python instalado) Generar un archivo autoextraible similar a un instalador (pero más "> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    @@ -104,20 +104,20 @@

    Empaquetando Programas De Python Para Windows

  • 7-Zip (opcional, para crear el archivo autoextraible)

  • Ejemplo

    Como ejemplo tomamos una aplicación simple hola.py:

    -
    # -*- coding: iso-8859-1 -*-
    -
    -print "hola mundo"
    +
    # -*- coding: iso-8859-1 -*-
    +
    +print "hola mundo"
     

    "Compilando" Python con Py2Exe

    Py2Exe empaqueta los archivos necesarios para ejecutar la aplicación sin necesitad de instalar Python ni sus dependencias.

    Para crear el ejecutable es necesario crear un script de setup que extiende las utilidades de distribución de python (DistUtils), setup.py:

    -
    from distutils.core import setup
    -import py2exe
    -
    -setup(console=['hola.py'])
    +
    from distutils.core import setup
    +import py2exe
    +
    +setup(console=['hola.py'])
     

    Luego en la carpeta de la aplicación, por línea de comandos, ejecutamos este script:

    -
    python setup.py py2exe
    +
    python setup.py py2exe
     

    Con lo que se generará una carpeta dist con los siguientes archivos:

      @@ -131,7 +131,7 @@

      Empaquetando Programas De Python Para Windows

    Creando un instalador simple con 7-Zip

    Con 7-zip se puede crear un único archivo comprimido autoextraible (ejecutable), con una muy buena tasa de compresión y de manera muy simple.

    Para ello, ejecutar 7-Zip en la linea de comandos sobre la carpeta de la aplicación:

    -
    7z.exe a -sfx setup.exe dist
    +
    7z.exe a -sfx setup.exe dist
     

    Con esto nos creará un archivo setup.exe que al ejecutarlo descomprimirá automáticamente la carpeta de nuestra aplicación. Este archivo contiene todo lo necesario para ejecutar la aplicación.

    Este ejemplo usa la línea de comando, pero también se puede usar la interfase visual integrada al explorador de windows de 7-Zip (click derecho sobre la carpeta dist, en el menú contextual elejir 7-zip, añadir al archivo, y tildar opción "Crear archivo SFX")

    diff --git a/recetario/crearejecutablewindowsdesdelinux/index.html b/recetario/crearejecutablewindowsdesdelinux/index.html index 4700f75f8..ab93a2bd4 100644 --- a/recetario/crearejecutablewindowsdesdelinux/index.html +++ b/recetario/crearejecutablewindowsdesdelinux/index.html @@ -35,7 +35,7 @@ Una distribución de Linux http://distrowatch.com/. Un Wine instal"> - + Ir al contenido principal @@ -69,12 +69,12 @@ - +
    @@ -111,11 +111,11 @@

    Empaquetando Programas De Python Para Windows Desde Linux

  • Inno Setup Compiler http://www.innosetup.com/

  • Instalando Python

    Para instalar el MSI de Python para Windows se usa:

    -
    $ wine msiexec /i python-2.5.1.msi
    +
    $ wine msiexec /i python-2.5.1.msi
     

    Luego instale las dependencias de su programa.

    Por ejemplo, para instalar pygame:

    -
    $ wine pygame-1.7.1release.win32-py2.5.exe
    +
    $ wine pygame-1.7.1release.win32-py2.5.exe
     

    O doble clic sobre el icono del programa.

    Es importante decirle que python haga los .pyc, cuando sea preguntado por el instalador.

    @@ -123,54 +123,54 @@

    Empaquetando Programas De Python Para Windows Desde Linux

    Aún habiendo hecho lo anterior, puede pasar que cuando se intenta "compilar",aparezca un mensaje que advierte que no se encontró un archivo .pyc, debe buscarse el .py correspondiente. Y ejecutarlo con (Repita la operación con cada modulo en el que aparezca el error)

    -
    $ cd directorio_del_modulo
    -$ wine ~/.wine/drive_c/Python25/python.exe -m modulo.py
    +
    $ cd directorio_del_modulo
    +$ wine ~/.wine/drive_c/Python25/python.exe -m modulo.py
     

    Es importante hacer notar que aunque alguna característica del programa puede NO funcionar en Wine, como por ejemplo pygame, igualmente puede "compilarse" (empaquetarse) correctamente.

    Pyinstaller

    Pyinstaller no se instala, como py2exe. Sin que se descomprime en un directorio. Se necesita un directorio por cada versión de Python que uno quiera usar con Pyinstaller.

    Para configurar Pyinstaller siga las instrucciones del manual.

    Lo que no es claro en el manual es como crear los ejecutables. La explicación es complicada y retorcida, sin embargo es muy sencillo. Ejecute algo como:

    -
    $ cd Pyinstaller-1.3
    -$ wine c:\\Python25\\python.exe Makespec.py --noconsole --out=c:\\miproyecto\\Pyinstallerdist c:\\miproyecto\\principal.py
    +
    $ cd Pyinstaller-1.3
    +$ wine c:\\Python25\\python.exe Makespec.py --noconsole --out=c:\\miproyecto\\Pyinstallerdist c:\\miproyecto\\principal.py
     

    Esto crea un archivo principal.spec en el directorio c:\miproyecto\Pyinstallerdist

    El archivo .spec se hace solo una vez, en general no es necesario cambiarlo.

    Para automatizar la compilación primero borramos lo que este hecho de antes, esto hace más lento el empaquetamiento, pero evitamos el riesgo de que se empaqueten cosas viejas con las nuevas. Especialmente si las modificaciones hechas son muy pequeñas.

    -
    $ rm ~/.wine/drive_c/miproyecto/Pyinstallerdist/buildmiproyecto/*.*
    -$ rm ~/.wine/drive_c/miproyecto/Pyinstallerdist/distmiproyecto/principal.exe
    +
    $ rm ~/.wine/drive_c/miproyecto/Pyinstallerdist/buildmiproyecto/*.*
    +$ rm ~/.wine/drive_c/miproyecto/Pyinstallerdist/distmiproyecto/principal.exe
     

    Luego creamos el ejecutable.

    -
    $ cd Pyinstaller-1.3
    -$ wine ~/.wine/drive_c/Python25/python.exe -O Build.py c:\\miproyecto\\Pyinstallerdist\\principal.spec
    +
    $ cd Pyinstaller-1.3
    +$ wine ~/.wine/drive_c/Python25/python.exe -O Build.py c:\\miproyecto\\Pyinstallerdist\\principal.spec
     

    A diferencia de py2exe, pyinstaller no copia automáticamente el archivo w9xpopen.exe así que lo copiamos:

    -
    $ cp ~/.wine/drive_c/Python25/w9xpopen.exe ~/.wine/drive_c/miproyecto/Pyinstallerdist/distprincipal/
    +
    $ cp ~/.wine/drive_c/Python25/w9xpopen.exe ~/.wine/drive_c/miproyecto/Pyinstallerdist/distprincipal/
     

    Esto solo es necesario hacerlo una vez.

    Inno Setup Compiler

    Inno Setup Compiler crea instaladores para Windows, funciona perfectamente bajo Linux con Wine. Es una aplicación sumamente fácil de usar, y tiene un asistente muy bueno. Por lo que no tiene sentido comentarla, sin embargo hay un truco que merece la pena.

    Para automatizar la creación del instalador de nuestra aplicación podemos ejecutar:

    -
    $ wine ~/.wine/drive_c/Archivos\ de\ programa/Inno\ Setup\ 5/ISCC.exe /Q "c:\miproyecto\iss\principal.iss"
    +
    $ wine ~/.wine/drive_c/Archivos\ de\ programa/Inno\ Setup\ 5/ISCC.exe /Q "c:\miproyecto\iss\principal.iss"
     

    Automátizando la creación del instalador

    Como se darán cuenta, todas estas instrucciones de linea de comando se pueden colocar en un archivo de Bash, y hacer que todo el proceso de empaquetado quede totalmente automatizado.

    -
    rm ~/.wine/drive_c/miproyecto/CDs/Nuevasideas/*.*
    -
    -cd Pyinstaller-1.3
    -rm ~/.wine/drive_c/miproyecto/Pyinstallerdist/buildprincipal/*.*
    -rm ~/.wine/drive_c/miproyecto/Pyinstallerdist/distprincipal/principal.exe
    -
    -wine ~/.wine/drive_c/Python25/python.exe -O Build.py c:\\miproyecto\\Pyinstallerdist\\principal.spec
    -
    -wine ~/.wine/drive_c/Archivos\ de\ programa/Inno\ Setup\ 5/ISCC.exe /Q "c:\miproyecto\iss\Nuevasideas.iss"
    -
    -cp ~/.wine/drive_c/miproyecto/principal.py ~/.wine/drive_c/miproyecto/CDs/Nuevasideas/Linux/bin
    -cp ~/.wine/drive_c/miproyecto/mimodulo.py ~/.wine/drive_c/miproyecto/CDs/Nuevasideas/Linux/bin
    -
    -cd ~/.wine/drive_c/miproyecto/CDs/Nuevasideas/
    -tar -cf Linux-Nuevasideas.tar Linux/
    -bzip2 Linux-Nuevasideas.tar
    +
    rm ~/.wine/drive_c/miproyecto/CDs/Nuevasideas/*.*
    +
    +cd Pyinstaller-1.3
    +rm ~/.wine/drive_c/miproyecto/Pyinstallerdist/buildprincipal/*.*
    +rm ~/.wine/drive_c/miproyecto/Pyinstallerdist/distprincipal/principal.exe
    +
    +wine ~/.wine/drive_c/Python25/python.exe -O Build.py c:\\miproyecto\\Pyinstallerdist\\principal.spec
    +
    +wine ~/.wine/drive_c/Archivos\ de\ programa/Inno\ Setup\ 5/ISCC.exe /Q "c:\miproyecto\iss\Nuevasideas.iss"
    +
    +cp ~/.wine/drive_c/miproyecto/principal.py ~/.wine/drive_c/miproyecto/CDs/Nuevasideas/Linux/bin
    +cp ~/.wine/drive_c/miproyecto/mimodulo.py ~/.wine/drive_c/miproyecto/CDs/Nuevasideas/Linux/bin
    +
    +cd ~/.wine/drive_c/miproyecto/CDs/Nuevasideas/
    +tar -cf Linux-Nuevasideas.tar Linux/
    +bzip2 Linux-Nuevasideas.tar
     
    diff --git a/recetario/crypto/blowfishconblowfishpy/index.html b/recetario/crypto/blowfishconblowfishpy/index.html index 2fde0e166..ebd628d94 100644 --- a/recetario/crypto/blowfishconblowfishpy/index.html +++ b/recetario/crypto/blowfishconblowfishpy/index.html @@ -28,7 +28,7 @@ ➜ crypto_example wget http://www.seanet.com/\~bugbee/crypto/blowfish/blowfish.py3 ➜ "> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    @@ -87,22 +87,22 @@

    Blowfish Con Blowfishpy

    Escribe acerca de Recetario/Crypto/BlowfishConBlowfishpy aquí.

    -
      ~  mkdir crypto_example
    -  ~  cd crypto_example
    -  crypto_example  wget http://www.seanet.com/\~bugbee/crypto/blowfish/blowfish.py3
    -  crypto_example  mv blowfish.py3 blowfish.py
    +
      ~  mkdir crypto_example
    +  ~  cd crypto_example
    +  crypto_example  wget http://www.seanet.com/\~bugbee/crypto/blowfish/blowfish.py3
    +  crypto_example  mv blowfish.py3 blowfish.py
     

    Con este código

    -
    import blowfish
    -
    -b = blowfish.Blowfish("secreto aca")
    -mensaje = "hola!..."
    -cifrado = b.encipher_block(mensaje)
    -
    -print "mensaje %s cifrado es %s" % (mensaje, cifrado)
    +
    import blowfish
    +
    +b = blowfish.Blowfish("secreto aca")
    +mensaje = "hola!..."
    +cifrado = b.encipher_block(mensaje)
    +
    +print "mensaje %s cifrado es %s" % (mensaje, cifrado)
     

    Salida:

    -
    mensaje hola!... cifrado es 0@�WE
    +
    mensaje hola!... cifrado es 0@�WE
     

    Nota: El mensaje a cifrar parece que tiene que tener un largo de 8 (no sé mucho de blowfish :D)

    diff --git a/recetario/dbfpy/index.html b/recetario/dbfpy/index.html index 133be7531..0eebeecbb 100644 --- a/recetario/dbfpy/index.html +++ b/recetario/dbfpy/index.html @@ -26,7 +26,7 @@ Esta receta es un ejemplo de cómo acceder nativamente desde Python a bases de datos en formato DBF (dBase, Foxpro, Clipper, etc.), sin necesidad de ODBC u otras herramientas. Utiliza DbfPy"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -90,35 +90,35 @@

    Dbfpy

    Nota: Para nuevos proyectos utilizar una base de datos relacional (ej. PostgreSQL o MySQL), o usar shelf para guardar objetos python fácilmente.

    Ejemplo:

    Ejemplo original traducido y ajustado:

    -
    # -*- coding: iso-8859-1 -*-
    -
    -from dbfpy.dbf import Dbf, DbfRecord
    -
    -# abro el archivo country.dbf(viene como ejemplo dentro de la libreria)
    -dbf1 = Dbf()
    -dbf1.openFile('dbfpy/county.dbf', readOnly=0)
    -dbf1.reportOn()
    -print 'registros de ejemplo:'
    -
    -# recorro los registros:
    -for registro in dbf1:
    -    # recorro los campos:
    -    for nombre_campo in dbf1.fieldNames():
    -        print '%s:\t %s' % (nombre_campo, registro[nombre_campo])
    -    print
    -
    -
    -# agregar un registro (campos COUNTYNO, COUNTYNAME, COUNTYABBR)
    -reg=DbfRecord(dbf1)
    -reg['COUNTYNO']=116
    -reg['COUNTYNAME']="Prueba"
    -reg['COUNTYABBR']="PRUE"
    -#reg['FECHA']=(2000,1,12)
    -reg.store()
    -
    -
    -# cierro el archivo
    -dbf1.close()
    +
    # -*- coding: iso-8859-1 -*-
    +
    +from dbfpy.dbf import Dbf, DbfRecord
    +
    +# abro el archivo country.dbf(viene como ejemplo dentro de la libreria)
    +dbf1 = Dbf()
    +dbf1.openFile('dbfpy/county.dbf', readOnly=0)
    +dbf1.reportOn()
    +print 'registros de ejemplo:'
    +
    +# recorro los registros:
    +for registro in dbf1:
    +    # recorro los campos:
    +    for nombre_campo in dbf1.fieldNames():
    +        print '%s:\t %s' % (nombre_campo, registro[nombre_campo])
    +    print
    +
    +
    +# agregar un registro (campos COUNTYNO, COUNTYNAME, COUNTYABBR)
    +reg=DbfRecord(dbf1)
    +reg['COUNTYNO']=116
    +reg['COUNTYNAME']="Prueba"
    +reg['COUNTYABBR']="PRUE"
    +#reg['FECHA']=(2000,1,12)
    +reg.store()
    +
    +
    +# cierro el archivo
    +dbf1.close()
     

    Autor / Autores:

    MarianoReingart

    diff --git a/recetario/decodehtmlentities/index.html b/recetario/decodehtmlentities/index.html index c1709acdb..b6a2a86f1 100644 --- a/recetario/decodehtmlentities/index.html +++ b/recetario/decodehtmlentities/index.html @@ -31,7 +31,7 @@ @param text The HTML (or XML) source t'> - + Ir al contenido principal @@ -65,12 +65,12 @@ - +
    @@ -89,40 +89,40 @@

    Decodificar Entities De Html

    -
    import re
    -import htmlentitydefs
    -
    -def unescape(text, encoding="UTF-8"):
    -    """
    -    Removes HTML or XML character references and entities from a text string.
    -
    -    @param text The HTML (or XML) source text.
    -    @return The unescaped text as a Unicode.
    -    """
    -
    -    def fixup(m):
    -        text = m.group(0)
    -        if text[:2] == "&#":
    -            # character reference
    -            try:
    -                if text[:3] == "&#x":
    -                    text = unichr(int(text[3:-1], 16))
    -                else:
    -                    text = unichr(int(text[2:-1]))
    -            except ValueError:
    -                pass
    -        else:
    -            # named entity
    -            try:
    -                text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
    -            except KeyError:
    -                pass
    -
    -        return text
    -
    -    # Decode string as needed
    -    text = text.decode(encoding) if isinstance(text, str) else text
    -    return text and re.sub("&#?\w+;", fixup, text)
    +    
    import re
    +import htmlentitydefs
    +
    +def unescape(text, encoding="UTF-8"):
    +    """
    +    Removes HTML or XML character references and entities from a text string.
    +
    +    @param text The HTML (or XML) source text.
    +    @return The unescaped text as a Unicode.
    +    """
    +
    +    def fixup(m):
    +        text = m.group(0)
    +        if text[:2] == "&#":
    +            # character reference
    +            try:
    +                if text[:3] == "&#x":
    +                    text = unichr(int(text[3:-1], 16))
    +                else:
    +                    text = unichr(int(text[2:-1]))
    +            except ValueError:
    +                pass
    +        else:
    +            # named entity
    +            try:
    +                text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
    +            except KeyError:
    +                pass
    +
    +        return text
    +
    +    # Decode string as needed
    +    text = text.decode(encoding) if isinstance(text, str) else text
    +    return text and re.sub("&#?\w+;", fixup, text)
     

    Gracias Martin Conte Mac Donell! 😉

    diff --git a/recetario/displaylcd7segmentos/index.html b/recetario/displaylcd7segmentos/index.html index 19e09f15c..6783f9788 100644 --- a/recetario/displaylcd7segmentos/index.html +++ b/recetario/displaylcd7segmentos/index.html @@ -26,7 +26,7 @@ Toma los sys.argv, tiene punto, tiene guion de negativo, tiene import con wilcard (ups!). Útil para importarlo dentro de otro program"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -88,265 +88,265 @@

    Display Lcd De 7 Segmentos

    Toma los sys.argv, tiene punto, tiene guion de negativo, tiene import con wilcard (ups!).

    Útil para importarlo dentro de otro programa para representar otras cosas.

    Screenshot:

    -/images/DisplayLCD7Segmentos/temp.jpg
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -try:
    -    from Tkinter import *  # Python2
    -except ImportError:
    -    from tkinter import *  # Python3
    -import time
    -import math
    -import sys
    -
    -def ledLit(pos, val):
    -    if val < 0:
    -        if pos == 1:
    -            return 1
    -        else:
    -            return 0
    -    else:
    -        lookup = (125,80,55,87,90,79,111,81,127,95)
    -        return (1<<pos) & lookup[val]
    -
    -class ResolveSegColor:
    -    def __init__(self, bg, fg):
    -        self.__bg, self.__fg = bg, fg
    -    def get(self, seg, val):
    -        if ledLit(seg, val):
    -            return self.__fg
    -        else:
    -            return self.__bg
    -
    -class Digit(Frame):
    -    def __init__(self, master, w, h, init = None):
    -        Frame.__init__(self, master)
    -        self.__bg, self.__fg = '#000000', '#0800FF'
    -        self.__lastVal = 0
    -        self.__dpon = 0
    -        self.__startx = self.__starty = 3
    -        self.setSize(h, w)
    -        self.__c = Canvas(self, width = w, height = h, bg=self.__bg, highlightthickness=0)
    -        self.__c.pack(side=TOP, fill=BOTH, expand=YES)
    -        self.__lines = []
    -        self.__dplines = []
    -        self.__makeLines()
    -        self.__rseg = ResolveSegColor(self.__bg, self.__fg)
    -        if init != None:
    -            self.draw(init)
    -
    -    def getCanvas(self):
    -        return self.__c
    -
    -    def setSize(self, h, w):
    -        self.__x = w - 6
    -        self.__y = h/2 - 4
    -        self.__w = min(self.__x, self.__y)/6
    -        if self.__w < 3:
    -            self.__w = 3
    -        self.__x = self.__x - self.__w - 1
    -
    -    def resizeEvent(self, event):
    -        self.setSize(event.height, event.width)
    -        self.__c.config(height = event.height, width = event.width)
    -        for i in self.__lines:
    -            self.__c.delete(i)
    -        del self.__lines[:]
    -        self.__lines = []
    -        self.__makeLines()
    -        self.draw(self.__lastVal)
    -
    -    def dpon(self):
    -        self.__dpon = 1
    -        for i in self.__dplines:
    -            self.__c.itemconfigure(i, fill = self.__fg)
    -
    -    def dpoff(self):
    -        self.__dpon = 0
    -        for i in self.__dplines:
    -            self.__c.itemconfigure(i, fill = self.__bg)
    -
    -    def refresh(self):
    -        self.draw(self.__lastVal)
    -
    -    def draw(self, val, dp = None):
    -        self.__lastVal = val
    -        if dp != None or self.__dpon:
    -            dpc = self.__fg
    -        else:
    -            dpc = self.__bg
    -        for i in range(self.__w):
    -            ii = i*8
    -            self.__c.itemconfigure(self.__lines[ii],
    -                                   fill = self.__rseg.get(0, val))
    -            if not i % 2:
    -                self.__c.itemconfigure(self.__lines[ii + 1],
    -                                       fill = self.__rseg.get(1, val))
    -            else:
    -                self.__c.itemconfigure(self.__lines[ii + 1],
    -                                       fill = self.__rseg.get(1, val))
    -            self.__c.itemconfigure(self.__lines[ii + 2],
    -                                   fill = self.__rseg.get(2, val))
    -            self.__c.itemconfigure(self.__lines[ii + 3],
    -                                   fill = self.__rseg.get(3, val))
    -            self.__c.itemconfigure(self.__lines[ii + 4],
    -                                   fill = self.__rseg.get(4, val))
    -            self.__c.itemconfigure(self.__lines[ii + 5],
    -                                   fill = self.__rseg.get(5, val))
    -            self.__c.itemconfigure(self.__lines[ii + 6],
    -                                   fill = self.__rseg.get(6, val))
    -            self.__c.itemconfigure(self.__lines[ii + 7], fill = dpc)
    -
    -    def clear(self):
    -        for i in self.__lines:
    -            self.__c.itemconfigure(i, fill = self.__bg)
    -
    -    def __makeLines(self):
    -        start_x, start_y = self.__startx, self.__starty
    -        x, y = self.__x, self.__y
    -        for i in range(self.__w):
    -            self.__lines.append(self.__c.create_line(start_x+1+i, start_y+i,
    -                                                     start_x+x-2-i, start_y+i,
    -                                                     fill = self.__bg))
    -            if not i % 2:
    -                self.__lines.append(self.__c.create_line(start_x+2+(i/2),
    -                                                         start_y+y-(i/2)+1,
    -                                                         start_x+x-3-(i/2),
    -                                                         start_y+y-(i/2)+1,
    -                                                         fill = self.__bg))
    -            else:
    -                self.__lines.append(self.__c.create_line(start_x+2+(i/2)+1,
    -                                                         start_y+y+(i/2)+2,
    -                                                         start_x+x-3-((i/2)+1),
    -                                                         start_y+y+(i/2)+2,
    -                                                         fill = self.__bg))
    -            self.__lines.append(self.__c.create_line(start_x+1+i,
    -                                                     start_y+2*y-i+2,
    -                                                     start_x+x-2-i,
    -                                                     start_y+2*y-i+2,
    -                                                     fill = self.__bg))
    -            self.__lines.append(self.__c.create_line(start_x+i, start_y+2+i,
    -                                                     start_x+i, start_y+y-i,
    -                                                     fill = self.__bg))
    -            self.__lines.append(self.__c.create_line(start_x+x-i-1,
    -                                                     start_y+2+i,
    -                                                     start_x+x-i-1,
    -                                                     start_y+y-i,
    -                                                     fill = self.__bg))
    -            self.__lines.append(self.__c.create_line(start_x+i, start_y+2+i+y,
    -                                                     start_x+i, start_y+2*y-i,
    -                                                     fill = self.__bg))
    -            self.__lines.append(self.__c.create_line(start_x+x-i-1,
    -                                                     start_y+2+i+y,
    -                                                     start_x+x-1-i,
    -                                                     start_y+2*y-i,
    -                                                     fill = self.__bg))
    -
    -            l = self.__c.create_line(start_x + x + 4,
    -                                     start_y +2*y - i,
    -                                     start_x + x + 4 + self.__w,
    -                                     start_y +2*y - i,
    -                                     fill = self.__bg)
    -            self.__lines.append(l)
    -            self.__dplines.append(l)
    -
    -class Display(Frame):
    -    def __init__(self, master, w, h, ndigits, orient = LEFT):
    -        Frame.__init__(self, master)
    -        self.__ndigits, self.__orient= ndigits, orient
    -        self.setSize(h, w)
    -        self.digits = []
    -        for i in range(ndigits):
    -            d = Digit(self, self.__w, self.__h)
    -            d.pack(side = orient, fill=BOTH, expand=YES)
    -            self.digits.append(d)
    -
    -    def int(self, val):
    -        if val < 0:
    -            negv = 1
    -            maxval = math.pow(10, self.__ndigits -1) -1
    -        else:
    -            negv = 0
    -            maxval = math.pow(10, self.__ndigits) - 1
    -        val = abs(val)
    -        if val > maxval:
    -            raise 'Error del rango'
    -        map(Digit.dpoff, self.digits)
    -        for i in range(1, self.__ndigits + 1):
    -            d = val%10
    -            self.digits[-i].draw(d)
    -            val = val/10
    -        if negv:
    -            self.digits[0].draw(-1)
    -
    -    def str(self, s):
    -        if '.' in s:
    -            l = len(s) - 1
    -        else:
    -            l = len(s)
    -        if l > self.__ndigits:
    -            raise 'Error del rango'
    -        map(Digit.dpoff, self.digits)
    -        p = 0
    -        for i in s:
    -            if i == '-':
    -                self.digits[p].draw(-1)
    -                p = p + 1
    -            elif i == '.':
    -                self.digits[p-1].dpon()
    -            else:
    -                if i == ' ':
    -                    self.digits[p].clear()
    -                else:
    -                    self.digits[p].draw(ord(i) - 0x30)
    -                p = p + 1
    -
    -    def float(self, val, format):
    -        self.str(format % (val))
    -
    -    def clear(self):
    -        map(Digit.clear, self.digits)
    -
    -    def setSize(self, h, w):
    -        if self.__orient == LEFT or self.__orient == RIGHT:
    -            self.__w = w/self.__ndigits
    -            self.__h = h
    -        elif self.__orient == TOP or self.__orient == BOTTOM:
    -            self.__h = h/self.__ndigits
    -            self.__w = w
    -
    -    def resizeEvent(self, event):
    -        self.setSize(event.height, event.width)
    -        for d in self.digits:
    -            event.height, event.width = self.__h, self.__w
    -            d.resizeEvent(event)
    -        self.refresh()
    -
    -    def refresh(self):
    -        map(Digit.refresh, self.digits)
    -
    -def updater(d, v):
    -    d.int(v)
    -    d.after(100, updater, d, v + 1)
    -
    -if __name__ == '__main__':
    -    root = Tk()
    -    root.title('Tienes 60 Segundos para salvar al Mundo')
    -    root.config(cursor='watch')
    -    root.focus()
    -    print (' ... G O !!!')
    -    ndigits = 3
    -    orient = LEFT
    -    if len(sys.argv) > 1:
    -        ndigits = int(sys.argv[1])
    -    if len(sys.argv) > 2:
    -        orient = TOP
    -    d = Display(root, 400, 100, ndigits, orient)
    -    d.bind('<Configure>', d.resizeEvent)
    -    d.bind('<Expose>', d.refresh())
    -    d.pack(fill=BOTH, expand=YES)
    -    updater(d, 0)
    -    root.mainloop()
    +/images/DisplayLCD7Segmentos/temp.jpg
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +try:
    +    from Tkinter import *  # Python2
    +except ImportError:
    +    from tkinter import *  # Python3
    +import time
    +import math
    +import sys
    +
    +def ledLit(pos, val):
    +    if val < 0:
    +        if pos == 1:
    +            return 1
    +        else:
    +            return 0
    +    else:
    +        lookup = (125,80,55,87,90,79,111,81,127,95)
    +        return (1<<pos) & lookup[val]
    +
    +class ResolveSegColor:
    +    def __init__(self, bg, fg):
    +        self.__bg, self.__fg = bg, fg
    +    def get(self, seg, val):
    +        if ledLit(seg, val):
    +            return self.__fg
    +        else:
    +            return self.__bg
    +
    +class Digit(Frame):
    +    def __init__(self, master, w, h, init = None):
    +        Frame.__init__(self, master)
    +        self.__bg, self.__fg = '#000000', '#0800FF'
    +        self.__lastVal = 0
    +        self.__dpon = 0
    +        self.__startx = self.__starty = 3
    +        self.setSize(h, w)
    +        self.__c = Canvas(self, width = w, height = h, bg=self.__bg, highlightthickness=0)
    +        self.__c.pack(side=TOP, fill=BOTH, expand=YES)
    +        self.__lines = []
    +        self.__dplines = []
    +        self.__makeLines()
    +        self.__rseg = ResolveSegColor(self.__bg, self.__fg)
    +        if init != None:
    +            self.draw(init)
    +
    +    def getCanvas(self):
    +        return self.__c
    +
    +    def setSize(self, h, w):
    +        self.__x = w - 6
    +        self.__y = h/2 - 4
    +        self.__w = min(self.__x, self.__y)/6
    +        if self.__w < 3:
    +            self.__w = 3
    +        self.__x = self.__x - self.__w - 1
    +
    +    def resizeEvent(self, event):
    +        self.setSize(event.height, event.width)
    +        self.__c.config(height = event.height, width = event.width)
    +        for i in self.__lines:
    +            self.__c.delete(i)
    +        del self.__lines[:]
    +        self.__lines = []
    +        self.__makeLines()
    +        self.draw(self.__lastVal)
    +
    +    def dpon(self):
    +        self.__dpon = 1
    +        for i in self.__dplines:
    +            self.__c.itemconfigure(i, fill = self.__fg)
    +
    +    def dpoff(self):
    +        self.__dpon = 0
    +        for i in self.__dplines:
    +            self.__c.itemconfigure(i, fill = self.__bg)
    +
    +    def refresh(self):
    +        self.draw(self.__lastVal)
    +
    +    def draw(self, val, dp = None):
    +        self.__lastVal = val
    +        if dp != None or self.__dpon:
    +            dpc = self.__fg
    +        else:
    +            dpc = self.__bg
    +        for i in range(self.__w):
    +            ii = i*8
    +            self.__c.itemconfigure(self.__lines[ii],
    +                                   fill = self.__rseg.get(0, val))
    +            if not i % 2:
    +                self.__c.itemconfigure(self.__lines[ii + 1],
    +                                       fill = self.__rseg.get(1, val))
    +            else:
    +                self.__c.itemconfigure(self.__lines[ii + 1],
    +                                       fill = self.__rseg.get(1, val))
    +            self.__c.itemconfigure(self.__lines[ii + 2],
    +                                   fill = self.__rseg.get(2, val))
    +            self.__c.itemconfigure(self.__lines[ii + 3],
    +                                   fill = self.__rseg.get(3, val))
    +            self.__c.itemconfigure(self.__lines[ii + 4],
    +                                   fill = self.__rseg.get(4, val))
    +            self.__c.itemconfigure(self.__lines[ii + 5],
    +                                   fill = self.__rseg.get(5, val))
    +            self.__c.itemconfigure(self.__lines[ii + 6],
    +                                   fill = self.__rseg.get(6, val))
    +            self.__c.itemconfigure(self.__lines[ii + 7], fill = dpc)
    +
    +    def clear(self):
    +        for i in self.__lines:
    +            self.__c.itemconfigure(i, fill = self.__bg)
    +
    +    def __makeLines(self):
    +        start_x, start_y = self.__startx, self.__starty
    +        x, y = self.__x, self.__y
    +        for i in range(self.__w):
    +            self.__lines.append(self.__c.create_line(start_x+1+i, start_y+i,
    +                                                     start_x+x-2-i, start_y+i,
    +                                                     fill = self.__bg))
    +            if not i % 2:
    +                self.__lines.append(self.__c.create_line(start_x+2+(i/2),
    +                                                         start_y+y-(i/2)+1,
    +                                                         start_x+x-3-(i/2),
    +                                                         start_y+y-(i/2)+1,
    +                                                         fill = self.__bg))
    +            else:
    +                self.__lines.append(self.__c.create_line(start_x+2+(i/2)+1,
    +                                                         start_y+y+(i/2)+2,
    +                                                         start_x+x-3-((i/2)+1),
    +                                                         start_y+y+(i/2)+2,
    +                                                         fill = self.__bg))
    +            self.__lines.append(self.__c.create_line(start_x+1+i,
    +                                                     start_y+2*y-i+2,
    +                                                     start_x+x-2-i,
    +                                                     start_y+2*y-i+2,
    +                                                     fill = self.__bg))
    +            self.__lines.append(self.__c.create_line(start_x+i, start_y+2+i,
    +                                                     start_x+i, start_y+y-i,
    +                                                     fill = self.__bg))
    +            self.__lines.append(self.__c.create_line(start_x+x-i-1,
    +                                                     start_y+2+i,
    +                                                     start_x+x-i-1,
    +                                                     start_y+y-i,
    +                                                     fill = self.__bg))
    +            self.__lines.append(self.__c.create_line(start_x+i, start_y+2+i+y,
    +                                                     start_x+i, start_y+2*y-i,
    +                                                     fill = self.__bg))
    +            self.__lines.append(self.__c.create_line(start_x+x-i-1,
    +                                                     start_y+2+i+y,
    +                                                     start_x+x-1-i,
    +                                                     start_y+2*y-i,
    +                                                     fill = self.__bg))
    +
    +            l = self.__c.create_line(start_x + x + 4,
    +                                     start_y +2*y - i,
    +                                     start_x + x + 4 + self.__w,
    +                                     start_y +2*y - i,
    +                                     fill = self.__bg)
    +            self.__lines.append(l)
    +            self.__dplines.append(l)
    +
    +class Display(Frame):
    +    def __init__(self, master, w, h, ndigits, orient = LEFT):
    +        Frame.__init__(self, master)
    +        self.__ndigits, self.__orient= ndigits, orient
    +        self.setSize(h, w)
    +        self.digits = []
    +        for i in range(ndigits):
    +            d = Digit(self, self.__w, self.__h)
    +            d.pack(side = orient, fill=BOTH, expand=YES)
    +            self.digits.append(d)
    +
    +    def int(self, val):
    +        if val < 0:
    +            negv = 1
    +            maxval = math.pow(10, self.__ndigits -1) -1
    +        else:
    +            negv = 0
    +            maxval = math.pow(10, self.__ndigits) - 1
    +        val = abs(val)
    +        if val > maxval:
    +            raise 'Error del rango'
    +        map(Digit.dpoff, self.digits)
    +        for i in range(1, self.__ndigits + 1):
    +            d = val%10
    +            self.digits[-i].draw(d)
    +            val = val/10
    +        if negv:
    +            self.digits[0].draw(-1)
    +
    +    def str(self, s):
    +        if '.' in s:
    +            l = len(s) - 1
    +        else:
    +            l = len(s)
    +        if l > self.__ndigits:
    +            raise 'Error del rango'
    +        map(Digit.dpoff, self.digits)
    +        p = 0
    +        for i in s:
    +            if i == '-':
    +                self.digits[p].draw(-1)
    +                p = p + 1
    +            elif i == '.':
    +                self.digits[p-1].dpon()
    +            else:
    +                if i == ' ':
    +                    self.digits[p].clear()
    +                else:
    +                    self.digits[p].draw(ord(i) - 0x30)
    +                p = p + 1
    +
    +    def float(self, val, format):
    +        self.str(format % (val))
    +
    +    def clear(self):
    +        map(Digit.clear, self.digits)
    +
    +    def setSize(self, h, w):
    +        if self.__orient == LEFT or self.__orient == RIGHT:
    +            self.__w = w/self.__ndigits
    +            self.__h = h
    +        elif self.__orient == TOP or self.__orient == BOTTOM:
    +            self.__h = h/self.__ndigits
    +            self.__w = w
    +
    +    def resizeEvent(self, event):
    +        self.setSize(event.height, event.width)
    +        for d in self.digits:
    +            event.height, event.width = self.__h, self.__w
    +            d.resizeEvent(event)
    +        self.refresh()
    +
    +    def refresh(self):
    +        map(Digit.refresh, self.digits)
    +
    +def updater(d, v):
    +    d.int(v)
    +    d.after(100, updater, d, v + 1)
    +
    +if __name__ == '__main__':
    +    root = Tk()
    +    root.title('Tienes 60 Segundos para salvar al Mundo')
    +    root.config(cursor='watch')
    +    root.focus()
    +    print (' ... G O !!!')
    +    ndigits = 3
    +    orient = LEFT
    +    if len(sys.argv) > 1:
    +        ndigits = int(sys.argv[1])
    +    if len(sys.argv) > 2:
    +        orient = TOP
    +    d = Display(root, 400, 100, ndigits, orient)
    +    d.bind('<Configure>', d.resizeEvent)
    +    d.bind('<Expose>', d.refresh())
    +    d.pack(fill=BOTH, expand=YES)
    +    updater(d, 0)
    +    root.mainloop()
     
    diff --git a/recetario/django/obtenerclaseoriginalcuandohayherencia/index.html b/recetario/django/obtenerclaseoriginalcuandohayherencia/index.html index e6223eedf..f44c87de0 100644 --- a/recetario/django/obtenerclaseoriginalcuandohayherencia/index.html +++ b/recetario/django/obtenerclaseoriginalcuandohayherencia/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    @@ -83,94 +83,94 @@

    Obtener Clase Original Cuando Hay Herencia

    Si usamos herencia normal de modelos (no abstracta), se vuelve difícil obtener el objeto original de la base de datos cuando sólo tenemos una referencia a un ancestro (esto pasa a menudo cuando tenemos relaciones a un modelo que fue derivado). Este cacho de código define una clase abstracta SubclassedModel, cuyos descendientes tienen en objects un Manager por defecto que devuelve directamente objetos de la clase con la que fueron creados.

    -
    from django.db import models
    -from django.db.models.query import QuerySet
    -from django.contrib.contenttypes.models import ContentType
    -
    -
    -def _as_original_class(inst):
    -    """
    -    Returns the instance that corresponds to `inst`
    -    in its original class.
    -    """
    -    model = inst.content_type.model_class()
    -    if (model == inst.__class__):
    -        return inst
    -    return model.objects.get(id=inst.id)
    -
    -
    -class OriginalClassQuerySet(QuerySet):
    -    """
    -    A QuerySet that returns original classes.
    -    """
    -    def __getitem__(self, k):
    -        result = super(OriginalClassQuerySet, self).__getitem__(k)
    -        if isinstance(result, models.Model):
    -            return _as_original_class(result)
    -        else:
    -            return result
    -
    -    def __iter__(self):
    -        for item in super(OriginalClassQuerySet, self).__iter__():
    -            yield _as_original_class(item)
    -
    -
    -class OriginalClassManager(models.Manager):
    -    """
    -    A Manager that fetches original classes.
    -    """
    -    def get_query_set(self):
    -        return OriginalClassQuerySet(self.model)
    -
    -
    -class SubclassedModel(models.Model):
    -    content_type = models.ForeignKey(ContentType, editable=False, null=True)
    -    objects = OriginalClassManager()
    -
    -    class Meta:
    -        abstract = True
    -
    -    def save(self, *args, **kwargs):
    -        if(not self.content_type):
    -            self.content_type = \
    -                ContentType.objects.get_for_model(self.__class__)
    -            super(SubclassedModel, self).save(*args, **kwargs)
    +
    from django.db import models
    +from django.db.models.query import QuerySet
    +from django.contrib.contenttypes.models import ContentType
    +
    +
    +def _as_original_class(inst):
    +    """
    +    Returns the instance that corresponds to `inst`
    +    in its original class.
    +    """
    +    model = inst.content_type.model_class()
    +    if (model == inst.__class__):
    +        return inst
    +    return model.objects.get(id=inst.id)
    +
    +
    +class OriginalClassQuerySet(QuerySet):
    +    """
    +    A QuerySet that returns original classes.
    +    """
    +    def __getitem__(self, k):
    +        result = super(OriginalClassQuerySet, self).__getitem__(k)
    +        if isinstance(result, models.Model):
    +            return _as_original_class(result)
    +        else:
    +            return result
    +
    +    def __iter__(self):
    +        for item in super(OriginalClassQuerySet, self).__iter__():
    +            yield _as_original_class(item)
    +
    +
    +class OriginalClassManager(models.Manager):
    +    """
    +    A Manager that fetches original classes.
    +    """
    +    def get_query_set(self):
    +        return OriginalClassQuerySet(self.model)
    +
    +
    +class SubclassedModel(models.Model):
    +    content_type = models.ForeignKey(ContentType, editable=False, null=True)
    +    objects = OriginalClassManager()
    +
    +    class Meta:
    +        abstract = True
    +
    +    def save(self, *args, **kwargs):
    +        if(not self.content_type):
    +            self.content_type = \
    +                ContentType.objects.get_for_model(self.__class__)
    +            super(SubclassedModel, self).save(*args, **kwargs)
     

    Para usarlo, supongamos el siguente models.py en la app example:

    -
    from django.db import models
    -from <el módulo de arriba> import SubclassedModel
    -
    -class Foo(SubclassedModel):
    -    [...]
    -    def __unicode__(self):
    -        return "A Foo"
    -
    -class Bar(Foo):
    -    [...]
    -    def __unicode__(self):
    -        return "A Bar"
    -
    -class Baz(Foo):
    -    [...]
    -    def __unicode__(self):
    -        return "A Baz"
    +
    from django.db import models
    +from <el módulo de arriba> import SubclassedModel
    +
    +class Foo(SubclassedModel):
    +    [...]
    +    def __unicode__(self):
    +        return "A Foo"
    +
    +class Bar(Foo):
    +    [...]
    +    def __unicode__(self):
    +        return "A Bar"
    +
    +class Baz(Foo):
    +    [...]
    +    def __unicode__(self):
    +        return "A Baz"
     

    Entonces:

    -
    $ django-admin.py shell --settings=<nombre del proyecto>.settings
    -Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
    -[GCC 4.4.3] on linux2
    -Type "help", "copyright", "credits" or "license" for more information.
    -(InteractiveConsole)
    ->>> from example import models
    ->>> bar_instance = models.Bar([...])
    ->>> bar_instance.save()
    ->>> baz_instance = models.Baz([...])
    ->>> baz_instance.save()
    ->>> foo_instance = models.Foo([...])
    ->>> foo_instance.save
    ->>> l = models.Foo.objects.all()
    ->>> l
    -[<A Bar>, <A Baz>, <A Foo>]
    +
    $ django-admin.py shell --settings=<nombre del proyecto>.settings
    +Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
    +[GCC 4.4.3] on linux2
    +Type "help", "copyright", "credits" or "license" for more information.
    +(InteractiveConsole)
    +>>> from example import models
    +>>> bar_instance = models.Bar([...])
    +>>> bar_instance.save()
    +>>> baz_instance = models.Baz([...])
    +>>> baz_instance.save()
    +>>> foo_instance = models.Foo([...])
    +>>> foo_instance.save
    +>>> l = models.Foo.objects.all()
    +>>> l
    +[<A Bar>, <A Baz>, <A Foo>]
     

    OJO: este mecanismo deshabilita el feature de Django según el cual un modelo no tiene un Manager por defecto cuando tiene cualquier Manager explícito. Se me ocurre que eso puede romper algo en subclases de SubclassedModel si uno no lo tiene en cuenta.

    diff --git a/recetario/django/testformularioconfileupload/index.html b/recetario/django/testformularioconfileupload/index.html index cd4f2373d..f0ba7073a 100644 --- a/recetario/django/testformularioconfileupload/index.html +++ b/recetario/django/testformularioconfileupload/index.html @@ -28,7 +28,7 @@ client = Client()"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    @@ -87,18 +87,18 @@

    Test Formulario Con File Upload En Django

    Un ejemplo de cómo probar un formulario que tiene un campo para subir un archivo.

    -
    from django.test.client import Client
    -from django.core.files.uploadedfile import SimpleUploadedFile
    -
    -client = Client()
    -client.login(username=username, password=password)
    -data = {'campo1': 'valor1',
    -        'campo2': 'valor2',
    -        'archivo': SimpleUploadedFile('nombre_de_archivo','contenido de archivo'),
    -}
    -
    -response = c.post('/path/al/form', data)
    -assert response.status_code == 200
    +
    from django.test.client import Client
    +from django.core.files.uploadedfile import SimpleUploadedFile
    +
    +client = Client()
    +client.login(username=username, password=password)
    +data = {'campo1': 'valor1',
    +        'campo2': 'valor2',
    +        'archivo': SimpleUploadedFile('nombre_de_archivo','contenido de archivo'),
    +}
    +
    +response = c.post('/path/al/form', data)
    +assert response.status_code == 200
     
    diff --git a/recetario/emailconadjunto/index.html b/recetario/emailconadjunto/index.html index d18a27c1d..148552a24 100644 --- a/recetario/emailconadjunto/index.html +++ b/recetario/emailconadjunto/index.html @@ -31,7 +31,7 @@ from email.mime.text import MIMEText fro"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - +
    @@ -92,40 +92,40 @@

    Email Con Adjunto

    Descripción

    Esta receta es un ejemplo sencillo de cómo enviar un email, con una parte de texto y otra binaria (adjunto)

    Ejemplo:

    -
    # -*- coding: iso-8859-1 -*-
    -from email.mime.text import MIMEText
    -from email.mime.application import MIMEApplication
    -from email.mime.multipart import MIMEMultipart
    -from smtplib import SMTP
    -
    -msg = MIMEMultipart()
    -msg['Subject'] = 'Esto es una prueba'
    -msg['From'] = 'yo@example.com'
    -msg['Reply-to'] = 'responder-aca@example.com'
    -msg['To'] = 'vos@example.com'
    -
    -# Esto es lo que se ve si uno no tiene un lector de mails como la gente:
    -msg.preamble = 'Mensaje de multiples partes.\n'
    -
    -# Esta es la parte textual:
    -part = MIMEText("Hola, te paso un archivo interesante")
    -msg.attach(part)
    -
    -# Esta es la parte binaria (puede ser cualquier extensión):
    -part = MIMEApplication(open("factura.pdf","rb").read())
    -part.add_header('Content-Disposition', 'attachment', filename="factura.pdf")
    -msg.attach(part)
    -
    -# Se pueden seguir agregando partes (texto, imágenes, datos binarios, etc.)
    -
    -# Crear una instancia del servidor para envio de correo (hacerlo una sola vez)
    -smtp = SMTP("smtp.example.com")
    -# Iniciar sesión en el servidor (si es necesario):
    -smtp.ehlo()
    -smtp.login("yo@example.com", "mipassword")
    -
    -# Enviar el mail (o los mails)
    -smtp.sendmail(msg['From'], msg['To'], msg.as_string())
    +
    # -*- coding: iso-8859-1 -*-
    +from email.mime.text import MIMEText
    +from email.mime.application import MIMEApplication
    +from email.mime.multipart import MIMEMultipart
    +from smtplib import SMTP
    +
    +msg = MIMEMultipart()
    +msg['Subject'] = 'Esto es una prueba'
    +msg['From'] = 'yo@example.com'
    +msg['Reply-to'] = 'responder-aca@example.com'
    +msg['To'] = 'vos@example.com'
    +
    +# Esto es lo que se ve si uno no tiene un lector de mails como la gente:
    +msg.preamble = 'Mensaje de multiples partes.\n'
    +
    +# Esta es la parte textual:
    +part = MIMEText("Hola, te paso un archivo interesante")
    +msg.attach(part)
    +
    +# Esta es la parte binaria (puede ser cualquier extensión):
    +part = MIMEApplication(open("factura.pdf","rb").read())
    +part.add_header('Content-Disposition', 'attachment', filename="factura.pdf")
    +msg.attach(part)
    +
    +# Se pueden seguir agregando partes (texto, imágenes, datos binarios, etc.)
    +
    +# Crear una instancia del servidor para envio de correo (hacerlo una sola vez)
    +smtp = SMTP("smtp.example.com")
    +# Iniciar sesión en el servidor (si es necesario):
    +smtp.ehlo()
    +smtp.login("yo@example.com", "mipassword")
    +
    +# Enviar el mail (o los mails)
    +smtp.sendmail(msg['From'], msg['To'], msg.as_string())
     

    Autor / Autores:

    MarianoReingart

    diff --git a/recetario/entendiendounicode/index.html b/recetario/entendiendounicode/index.html index e8107791a..eecd48c9b 100644 --- a/recetario/entendiendounicode/index.html +++ b/recetario/entendiendounicode/index.html @@ -28,7 +28,7 @@ El nivel de la en'> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    @@ -86,7 +86,7 @@

    Entendiendounicode

    -
    < dash> herrFoo: the difference between a unicode string and an encoded byte string is exactly the same kind of difference as between the list [1, 2, 3] and the string "[1, 2, 3]"
    +    
    < dash> herrFoo: the difference between a unicode string and an encoded byte string is exactly the same kind of difference as between the list [1, 2, 3] and the string "[1, 2, 3]"
     

    @@ -99,17 +99,17 @@

    Entendiendounicode

    Todo estaría de maravillas sino fuera que Encodings hay millones. Estos mapeos fueron establecidos casi independientemente en muchas empresas y países del mundo, cada uno prácticamente con el suyo. La mayoría de los Encodings usan sólo un byte (8 bits) para almacenar el número, así que sólo cabía la posibilidad de 256 símbolos, lo cual claramente no alcanza para todos los símbolos del mundo. Piensen por ejemplo en los idiomas que no usan ni siquiera como base al alfabeto latín. Así es que terminamos con cientos de Encodings llamados 'latin1', 'utf-8', 'cp-1250' y cosas más esotéricas.

    Para resolver este problema es que se inventó Unicode (cualquier semejanza con http://xkcd.com/927/ es un error de concepto; ahora explico porqué). Unicode no es un encoding, aunque se asemeja mucho. Unicode es una serie de tablas de símbolos, nada más. Estos símbolos son no sólo aquellos que encontramos en todos los encodings habidos y por haber (incluyendo la mayoría de los alfabetos usados en el mundo, incluyendo el ya mencionado Braille, y hasta ficticios, como el klingon [sí, klingon, no pregunten]), sino muchos, muchos, muchos más. Demasiados, quizás. Para muestra vale un botón: http://www.fileformat.info/info/unicode/char/1f4a9/index.htm

    La ventaja de Unicode es que al contener todo, es posible que, dado un Encoding, se pueden encontrar los símbolos que abarca y hacer una traducción Unicode <-> Encoding. Al paso hacia la derecha se le llama Encodeado y la inversa Decodeado. Ver Unicode en una filmina. Notar que como Unicode es más grande (o igual?) que cualquier Encoding, hay símbolos en Unicode que no están en un Encoding dado. El Encodeado de un carácter no presente en el Encoding resulta en el fatídico y über-odiado mensaje:

    -
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
    +
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
     

    Unicode, Encodings y Python

    ¿Qué tiene tooooodo esto que ver con Python? Bueno, los no muy frescos de zabiola ya se habrán dado cuenta que al fin y al cabo Python corre sobre computadoras y Python maneja cadenas de caracteres (strings). Para dicho propósito Python tiene dos tipos distintos. Inicialmente, en Python2 usa el tipo unicode para representar bichos Unicode y str para representar bichos Encodeados. Esto suele traer millones de dolores de cabeza, pues el tipo str es mayormente (mal) usado en tutoriales para almacenar cadenas de caracteres, cuando se debería usar Unicode. ya explico porqué.

    Para complicar las cosas[2], Python3, en cambio, tiene otros dos tipos para ello: str se usa para el almacenamiento de cadenas de caracteres Unicode y bytes para bichos Encodeados. De aquí en más seguiré con la nomenclatura de Python2; si están usando Python3, agreguen a su ensalada el hecho de que cada vez que diga unicode ustedes deben pensar en str, y cuando diga str, ustedes piensen en bytes. Cuando Python3 sea más utilizado, y si aún estoy vivo y con uso de mis facultades, volveré a esta página y les juro que pongo todo en nomenclatura Python3.

    Entonces, tamos listoso0 con la nomenclatura: unicode para bichos Unicode y str para bichos Encodeados. La forma de crear un bicho Unicode es muy simple[1]:

    -
    a= u'Aló mundo!'
    +
    a= u'Aló mundo!'
     

    El source también existe, y está encodeado

    ¿Vieron ese [1] que puse más arriba? Bueno, resulta que hay una mentira casi tan grande como una casa en todo esto. Más que una mentira, una vuelta más de rosca. ¿Vieron que dije que cuando uno deja el mundo Python/Unicode uno pasa al mundo Encodeado? Bueno, les cuento, y agárrensé: Los archivos que contienen el código fuente de su programa Python también están Encodeados. Esto trae como consecuencia...

    -
    # -*- coding: utf-8 -*-
    +
    # -*- coding: utf-8 -*-
     

    Ver también:

      diff --git a/recetario/estilosrst2pdf/index.html b/recetario/estilosrst2pdf/index.html index 7304b1e2a..47c819a46 100644 --- a/recetario/estilosrst2pdf/index.html +++ b/recetario/estilosrst2pdf/index.html @@ -33,7 +33,7 @@ En el svn de rst2pdf se puede ver un archivo de ejemplo, que define todos los atributos posibles. En rst2pdf un estilo (est"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - +
    diff --git a/recetario/extraermails/index.html b/recetario/extraermails/index.html index 2f7fd3352..8aa555353 100644 --- a/recetario/extraermails/index.html +++ b/recetario/extraermails/index.html @@ -29,7 +29,7 @@ El código anterior devuelve una lista de strings, donde cada string es una "> - + Ir al contenido principal @@ -63,12 +63,12 @@ - +
    @@ -88,17 +88,17 @@

    Extraer Direcciones De Email De Un Texto

    Código

    -
    >>> import re
    ->>> mailsrch = re.compile(r'[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}')
    ->>> mailsrch.findall(texto)
    +
    >>> import re
    +>>> mailsrch = re.compile(r'[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}')
    +>>> mailsrch.findall(texto)
     

    El código anterior devuelve una lista de strings, donde cada string es una dirección de email. El texto original puede contener basura como espacios, comas u otros caracteres.

    Ahora podemos atrapar al asesino sin recurrir a Perl!!

    La expresión regular que sigue es del proyecto django.

    -
    email_re = re.compile(
    -            r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
    -            r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
    -            r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE)  # domain
    +
    email_re = re.compile(
    +            r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
    +            r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
    +            r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE)  # domain
     

    Se puede utilizar en la receta de Juanjo arriba.

    Autor

    diff --git a/recetario/facturapyfpdf/index.html b/recetario/facturapyfpdf/index.html index f939fe21a..e8fa458e0 100644 --- a/recetario/facturapyfpdf/index.html +++ b/recetario/facturapyfpdf/index.html @@ -26,7 +26,7 @@ Esta receta es un ejemplo sencillo de cómo generar una factura en PDF utilizando la libreria PyFpdf (port de FPDF para python). Para más detalles sobre la libreria PyFpdf y bajar una versi"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -90,272 +90,272 @@

    Factura Con Pyfpdf

    La factura incluye logo, recuadros, textos y código de barra entrelazado 2 de 5, en un formato aplicable en Argentina. Ver muestra adjunta:

    Este ejemplo esta harcodeado, en la vida real habría que abstraerlo en alguna especie de plantilla para facilitar su modificación.

    Ejemplo:

    -
    # -*- coding: iso-8859-1 -*-
    -
    -import os
    -from PyFPDF import FPDF
    -
    -pdf = FPDF()
    -pdf.AddPage()
    -pdf.SetFont('arial', '', 13.0)
    -pdf.SetXY(105.0, 8.0)
    -pdf.Cell(ln=0, h=22.0, align='C', w=75.0, txt='Comprobante de Ejemplo', border=0)
    -pdf.SetLineWidth(0.0)
    -pdf.Rect(15.0, 15.0, 170.0, 245.0)
    -pdf.SetLineWidth(0.0)
    -pdf.Rect(95.0, 15.0, 10.0, 10.0)
    -pdf.Image('serpiente.png', 20.0, 17.0, link='', type='', w=13.0, h=13.0)
    -pdf.SetFont('arial', 'B', 16.0)
    -pdf.SetXY(95.0, 18.0)
    -pdf.Cell(ln=0, h=2.0, align='C', w=10.0, txt='X', border=0)
    -pdf.SetFont('arial', '', 8.0)
    -pdf.SetXY(105.0, 21.0)
    -pdf.Cell(ln=0, h=4.0, align='C', w=75.0, txt='Original', border=0)
    -pdf.SetFont('arial', 'B', 7.0)
    -pdf.SetXY(95.0, 21.5)
    -pdf.Cell(ln=0, h=4.5, align='C', w=10.0, txt='COD.00', border=0)
    -pdf.SetLineWidth(0.0)
    -pdf.Line(100.0, 25.0, 100.0, 57.0)
    -pdf.SetFont('arial', 'B', 14.0)
    -pdf.SetXY(125.0, 25.5)
    -pdf.Cell(ln=0, h=9.5, align='L', w=60.0, txt='00000001', border=0)
    -pdf.SetXY(115.0, 27.5)
    -pdf.Cell(ln=0, h=5.5, align='L', w=10.0, txt='N\xba: ', border=0)
    -pdf.SetFont('arial', 'B', 12.0)
    -pdf.SetXY(17.0, 32.5)
    -pdf.Cell(ln=0, h=5.0, align='L', w=98.0, txt='EMPRESA', border=0)
    -pdf.SetFont('arial', '', 12.0)
    -pdf.SetXY(115.0, 33.0)
    -pdf.Cell(ln=0, h=7.0, align='L', w=60.0, txt='Fecha:', border=0)
    -pdf.SetXY(135.0, 33.0)
    -pdf.Cell(ln=0, h=7.0, align='L', w=40.0, txt='19/02/2009', border=0)
    -pdf.SetLineWidth(0.0)
    -pdf.Line(15.0, 57.0, 185.0, 57.0)
    -pdf.SetFont('arial', '', 10.0)
    -pdf.SetXY(17.0, 59.0)
    -pdf.Cell(ln=0, h=6.0, align='L', w=13.0, txt='Sr.(s):', border=0)
    -pdf.SetXY(35.0, 59.0)
    -pdf.Cell(ln=0, h=6.0, align='L', w=140.0, txt='Mariano Reingart', border=0)
    -pdf.SetXY(17.0, 64.0)
    -pdf.Cell(ln=0, h=6.0, align='L', w=18.0, txt='Domicilio:', border=0)
    -pdf.SetXY(35.0, 64.0)
    -pdf.Cell(ln=0, h=6.0, align='L', w=125.0, txt='Siempreviva 12345', border=0)
    -pdf.SetXY(17.0, 69.0)
    -pdf.Cell(ln=0, h=6.0, align='L', w=18.0, txt='Tel\xe9fono:', border=0)
    -pdf.SetXY(35.0, 69.0)
    -pdf.Cell(ln=0, h=6.0, align='L', w=80.0, txt='+1-5555-5555', border=0)
    -pdf.SetXY(115.0, 69.0)
    -pdf.Cell(ln=0, h=6.0, align='L', w=18.0, txt='Localidad:', border=0)
    -pdf.SetXY(133.0, 69.0)
    -pdf.Cell(ln=0, h=6.0, align='L', w=42.0, txt='Springfield', border=0)
    -pdf.SetLineWidth(0.0)
    -pdf.Line(15.0, 77.0, 185.0, 77.0)
    -pdf.SetXY(17.0, 80.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=15.0, txt='IVA:', border=0)
    -pdf.SetXY(35.0, 80.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=70.0, txt='Responsable', border=0)
    -pdf.SetXY(115.0, 80.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=20.0, txt='CUIT:', border=0)
    -pdf.SetXY(135.0, 80.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=40.0, txt='10-12345678-9', border=0)
    -pdf.SetLineWidth(0.0)
    -pdf.Line(15.0, 88.0, 185.0, 88.0)
    -pdf.SetXY(17.0, 90.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=48.0, txt='Fecha de Vencimiento Pago:', border=0)
    -pdf.SetXY(65.0, 90.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=20.0, txt='23/07/1978', border=0)
    -pdf.SetXY(92.0, 90.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=43.0, txt='Per\xedodo Facturado', border=0)
    -pdf.SetXY(125.0, 90.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=20.0, txt='01/01/2009', border=0)
    -pdf.SetXY(150.0, 90.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=20.0, txt='31/01/2009', border=0)
    -pdf.SetLineWidth(0.0)
    -pdf.Line(15.0, 95.0, 185.0, 95.0)
    -pdf.SetLineWidth(0.0)
    -pdf.Line(155.0, 95.0, 155.0, 230.0)
    -pdf.SetXY(20.0, 97.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=125.0, txt='Descripci\xf3n', border=0)
    -pdf.SetXY(160.0, 97.0)
    -pdf.Cell(ln=0, h=5.0, align='R', w=20.0, txt='Importe', border=0)
    -pdf.SetLineWidth(0.0)
    -pdf.Line(15.0, 102.0, 185.0, 102.0)
    -pdf.SetXY(20.0, 103.0)
    -pdf.Cell(ln=0, h=7.0, align='L', w=125.0, txt='Esto es una prueba y no es v\xe1lido como factura', border=0)
    -pdf.SetXY(160.0, 103.0)
    -pdf.Cell(ln=0, h=7.0, align='R', w=20.0, txt='100,00', border=0)
    -pdf.SetLineWidth(0.0)
    -pdf.Line(15.0, 230.0, 185.0, 230.0)
    -pdf.SetXY(20.0, 233.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=95.0, txt='CAE N\xba', border=0)
    -pdf.SetXY(45.0, 233.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=30.0, txt='01234567890', border=0)
    -pdf.SetFont('arial', '', 12.0)
    -pdf.SetXY(105.0, 234.0)
    -pdf.Cell(ln=0, h=9.0, align='R', w=45.0, txt='NETO GRAVADO:', border=0)
    -pdf.SetFont('arial', 'B', 12.0)
    -pdf.SetXY(145.0, 234.0)
    -pdf.Cell(ln=0, h=9.0, align='R', w=33.0, txt='100,00', border=0)
    -pdf.SetFont('arial', '', 10.0)
    -pdf.SetXY(20.0, 238.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=95.0, txt='Fecha Vto. CAE:', border=0)
    -pdf.SetXY(55.0, 238.0)
    -pdf.Cell(ln=0, h=5.0, align='L', w=30.0, txt='19/02/2009', border=0)
    -pdf.SetFont('arial', '', 12.0)
    -pdf.SetXY(125.0, 241.0)
    -pdf.Cell(ln=0, h=9.0, align='R', w=25.0, txt='IVA 21%:', border=0)
    -pdf.SetFont('arial', 'B', 12.0)
    -pdf.SetXY(145.0, 241.0)
    -pdf.Cell(ln=0, h=9.0, align='R', w=33.0, txt='21,00', border=0)
    -pdf.Interleaved2of5('012345678905', 20.0, 243.5, w=0.75)
    -pdf.SetFont('arial', 'B', 12.0)
    -pdf.SetXY(105.0, 251.0)
    -pdf.Cell(ln=0, h=9.0, align='R', w=73.0, txt='121,00', border=0)
    -pdf.SetFont('arial', '', 12.0)
    -pdf.SetXY(125.0, 251.0)
    -pdf.Cell(ln=0, h=9.0, align='R', w=25.0, txt='Total:', border=0)
    -pdf.SetLineWidth(0.0)
    -pdf.Rect(155.0, 252.0, 25.0, 7.0)
    -pdf.SetFont('arial', '', 10.0)
    -pdf.SetXY(20.0, 253.0)
    -pdf.Cell(ln=0, h=7.0, align='L', w=120.0, txt='012345678905', border=0)
    -pdf.Output('c:/factura.pdf', 'F')
    -
    -os.system("c:/factura.pdf")
    +
    # -*- coding: iso-8859-1 -*-
    +
    +import os
    +from PyFPDF import FPDF
    +
    +pdf = FPDF()
    +pdf.AddPage()
    +pdf.SetFont('arial', '', 13.0)
    +pdf.SetXY(105.0, 8.0)
    +pdf.Cell(ln=0, h=22.0, align='C', w=75.0, txt='Comprobante de Ejemplo', border=0)
    +pdf.SetLineWidth(0.0)
    +pdf.Rect(15.0, 15.0, 170.0, 245.0)
    +pdf.SetLineWidth(0.0)
    +pdf.Rect(95.0, 15.0, 10.0, 10.0)
    +pdf.Image('serpiente.png', 20.0, 17.0, link='', type='', w=13.0, h=13.0)
    +pdf.SetFont('arial', 'B', 16.0)
    +pdf.SetXY(95.0, 18.0)
    +pdf.Cell(ln=0, h=2.0, align='C', w=10.0, txt='X', border=0)
    +pdf.SetFont('arial', '', 8.0)
    +pdf.SetXY(105.0, 21.0)
    +pdf.Cell(ln=0, h=4.0, align='C', w=75.0, txt='Original', border=0)
    +pdf.SetFont('arial', 'B', 7.0)
    +pdf.SetXY(95.0, 21.5)
    +pdf.Cell(ln=0, h=4.5, align='C', w=10.0, txt='COD.00', border=0)
    +pdf.SetLineWidth(0.0)
    +pdf.Line(100.0, 25.0, 100.0, 57.0)
    +pdf.SetFont('arial', 'B', 14.0)
    +pdf.SetXY(125.0, 25.5)
    +pdf.Cell(ln=0, h=9.5, align='L', w=60.0, txt='00000001', border=0)
    +pdf.SetXY(115.0, 27.5)
    +pdf.Cell(ln=0, h=5.5, align='L', w=10.0, txt='N\xba: ', border=0)
    +pdf.SetFont('arial', 'B', 12.0)
    +pdf.SetXY(17.0, 32.5)
    +pdf.Cell(ln=0, h=5.0, align='L', w=98.0, txt='EMPRESA', border=0)
    +pdf.SetFont('arial', '', 12.0)
    +pdf.SetXY(115.0, 33.0)
    +pdf.Cell(ln=0, h=7.0, align='L', w=60.0, txt='Fecha:', border=0)
    +pdf.SetXY(135.0, 33.0)
    +pdf.Cell(ln=0, h=7.0, align='L', w=40.0, txt='19/02/2009', border=0)
    +pdf.SetLineWidth(0.0)
    +pdf.Line(15.0, 57.0, 185.0, 57.0)
    +pdf.SetFont('arial', '', 10.0)
    +pdf.SetXY(17.0, 59.0)
    +pdf.Cell(ln=0, h=6.0, align='L', w=13.0, txt='Sr.(s):', border=0)
    +pdf.SetXY(35.0, 59.0)
    +pdf.Cell(ln=0, h=6.0, align='L', w=140.0, txt='Mariano Reingart', border=0)
    +pdf.SetXY(17.0, 64.0)
    +pdf.Cell(ln=0, h=6.0, align='L', w=18.0, txt='Domicilio:', border=0)
    +pdf.SetXY(35.0, 64.0)
    +pdf.Cell(ln=0, h=6.0, align='L', w=125.0, txt='Siempreviva 12345', border=0)
    +pdf.SetXY(17.0, 69.0)
    +pdf.Cell(ln=0, h=6.0, align='L', w=18.0, txt='Tel\xe9fono:', border=0)
    +pdf.SetXY(35.0, 69.0)
    +pdf.Cell(ln=0, h=6.0, align='L', w=80.0, txt='+1-5555-5555', border=0)
    +pdf.SetXY(115.0, 69.0)
    +pdf.Cell(ln=0, h=6.0, align='L', w=18.0, txt='Localidad:', border=0)
    +pdf.SetXY(133.0, 69.0)
    +pdf.Cell(ln=0, h=6.0, align='L', w=42.0, txt='Springfield', border=0)
    +pdf.SetLineWidth(0.0)
    +pdf.Line(15.0, 77.0, 185.0, 77.0)
    +pdf.SetXY(17.0, 80.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=15.0, txt='IVA:', border=0)
    +pdf.SetXY(35.0, 80.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=70.0, txt='Responsable', border=0)
    +pdf.SetXY(115.0, 80.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=20.0, txt='CUIT:', border=0)
    +pdf.SetXY(135.0, 80.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=40.0, txt='10-12345678-9', border=0)
    +pdf.SetLineWidth(0.0)
    +pdf.Line(15.0, 88.0, 185.0, 88.0)
    +pdf.SetXY(17.0, 90.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=48.0, txt='Fecha de Vencimiento Pago:', border=0)
    +pdf.SetXY(65.0, 90.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=20.0, txt='23/07/1978', border=0)
    +pdf.SetXY(92.0, 90.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=43.0, txt='Per\xedodo Facturado', border=0)
    +pdf.SetXY(125.0, 90.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=20.0, txt='01/01/2009', border=0)
    +pdf.SetXY(150.0, 90.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=20.0, txt='31/01/2009', border=0)
    +pdf.SetLineWidth(0.0)
    +pdf.Line(15.0, 95.0, 185.0, 95.0)
    +pdf.SetLineWidth(0.0)
    +pdf.Line(155.0, 95.0, 155.0, 230.0)
    +pdf.SetXY(20.0, 97.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=125.0, txt='Descripci\xf3n', border=0)
    +pdf.SetXY(160.0, 97.0)
    +pdf.Cell(ln=0, h=5.0, align='R', w=20.0, txt='Importe', border=0)
    +pdf.SetLineWidth(0.0)
    +pdf.Line(15.0, 102.0, 185.0, 102.0)
    +pdf.SetXY(20.0, 103.0)
    +pdf.Cell(ln=0, h=7.0, align='L', w=125.0, txt='Esto es una prueba y no es v\xe1lido como factura', border=0)
    +pdf.SetXY(160.0, 103.0)
    +pdf.Cell(ln=0, h=7.0, align='R', w=20.0, txt='100,00', border=0)
    +pdf.SetLineWidth(0.0)
    +pdf.Line(15.0, 230.0, 185.0, 230.0)
    +pdf.SetXY(20.0, 233.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=95.0, txt='CAE N\xba', border=0)
    +pdf.SetXY(45.0, 233.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=30.0, txt='01234567890', border=0)
    +pdf.SetFont('arial', '', 12.0)
    +pdf.SetXY(105.0, 234.0)
    +pdf.Cell(ln=0, h=9.0, align='R', w=45.0, txt='NETO GRAVADO:', border=0)
    +pdf.SetFont('arial', 'B', 12.0)
    +pdf.SetXY(145.0, 234.0)
    +pdf.Cell(ln=0, h=9.0, align='R', w=33.0, txt='100,00', border=0)
    +pdf.SetFont('arial', '', 10.0)
    +pdf.SetXY(20.0, 238.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=95.0, txt='Fecha Vto. CAE:', border=0)
    +pdf.SetXY(55.0, 238.0)
    +pdf.Cell(ln=0, h=5.0, align='L', w=30.0, txt='19/02/2009', border=0)
    +pdf.SetFont('arial', '', 12.0)
    +pdf.SetXY(125.0, 241.0)
    +pdf.Cell(ln=0, h=9.0, align='R', w=25.0, txt='IVA 21%:', border=0)
    +pdf.SetFont('arial', 'B', 12.0)
    +pdf.SetXY(145.0, 241.0)
    +pdf.Cell(ln=0, h=9.0, align='R', w=33.0, txt='21,00', border=0)
    +pdf.Interleaved2of5('012345678905', 20.0, 243.5, w=0.75)
    +pdf.SetFont('arial', 'B', 12.0)
    +pdf.SetXY(105.0, 251.0)
    +pdf.Cell(ln=0, h=9.0, align='R', w=73.0, txt='121,00', border=0)
    +pdf.SetFont('arial', '', 12.0)
    +pdf.SetXY(125.0, 251.0)
    +pdf.Cell(ln=0, h=9.0, align='R', w=25.0, txt='Total:', border=0)
    +pdf.SetLineWidth(0.0)
    +pdf.Rect(155.0, 252.0, 25.0, 7.0)
    +pdf.SetFont('arial', '', 10.0)
    +pdf.SetXY(20.0, 253.0)
    +pdf.Cell(ln=0, h=7.0, align='L', w=120.0, txt='012345678905', border=0)
    +pdf.Output('c:/factura.pdf', 'F')
    +
    +os.system("c:/factura.pdf")
     
    -
    # -*- coding: iso-8859-1 -*-
    -#Actualizado 24/08/2012
    -import os
    -from fpdf import FPDF
    -
    -pdf = FPDF()
    -pdf.add_page(orientation='P')
    -pdf.set_font('arial', '', 13.0)
    -pdf.set_xy(105.0, 8.0)
    -pdf.cell(ln=0, h=22.0, align='C', w=75.0, txt='Comprobante de Ejemplo', border=0)
    -pdf.set_line_width(0.0)
    -pdf.rect(15.0, 15.0, 170.0, 245.0)
    -pdf.set_line_width(0.0)
    -pdf.rect(95.0, 15.0, 10.0, 10.0)
    -#descomentar para poner imagen de la serpiente
    -#pdf.image('serpiente.png', 20.0, 17.0, link='', type='', w=13.0, h=13.0)
    -pdf.set_font('arial', 'B', 16.0)
    -pdf.set_xy(95.0, 18.0)
    -pdf.cell(ln=0, h=2.0, align='C', w=10.0, txt='X', border=0)
    -pdf.set_font('arial', '', 8.0)
    -pdf.set_xy(105.0, 21.0)
    -pdf.cell(ln=0, h=4.0, align='C', w=75.0, txt='Original', border=0)
    -pdf.set_font('arial', 'B', 7.0)
    -pdf.set_xy(95.0, 21.5)
    -pdf.cell(ln=0, h=4.5, align='C', w=10.0, txt='COD.00', border=0)
    -pdf.set_line_width(0.0)
    -pdf.line(100.0, 25.0, 100.0, 57.0)
    -pdf.set_font('arial', 'B', 14.0)
    -pdf.set_xy(125.0, 25.5)
    -pdf.cell(ln=0, h=9.5, align='L', w=60.0, txt='00000001', border=0)
    -pdf.set_xy(115.0, 27.5)
    -pdf.cell(ln=0, h=5.5, align='L', w=10.0, txt='N\xba: ', border=0)
    -pdf.set_font('arial', 'B', 12.0)
    -pdf.set_xy(17.0, 32.5)
    -pdf.cell(ln=0, h=5.0, align='L', w=98.0, txt='EMPRESA', border=0)
    -pdf.set_font('arial', '', 12.0)
    -pdf.set_xy(115.0, 33.0)
    -pdf.cell(ln=0, h=7.0, align='L', w=60.0, txt='Fecha:', border=0)
    -pdf.set_xy(135.0, 33.0)
    -pdf.cell(ln=0, h=7.0, align='L', w=40.0, txt='19/02/2009', border=0)
    -pdf.set_line_width(0.0)
    -pdf.line(15.0, 57.0, 185.0, 57.0)
    -pdf.set_font('arial', '', 10.0)
    -pdf.set_xy(17.0, 59.0)
    -pdf.cell(ln=0, h=6.0, align='L', w=13.0, txt='Sr.(s):', border=0)
    -pdf.set_xy(35.0, 59.0)
    -pdf.cell(ln=0, h=6.0, align='L', w=140.0, txt='Mariano Reingart', border=0)
    -pdf.set_xy(17.0, 64.0)
    -pdf.cell(ln=0, h=6.0, align='L', w=18.0, txt='Domicilio:', border=0)
    -pdf.set_xy(35.0, 64.0)
    -pdf.cell(ln=0, h=6.0, align='L', w=125.0, txt='Siempreviva 12345', border=0)
    -pdf.set_xy(17.0, 69.0)
    -pdf.cell(ln=0, h=6.0, align='L', w=18.0, txt='Tel\xe9fono:', border=0)
    -pdf.set_xy(35.0, 69.0)
    -pdf.cell(ln=0, h=6.0, align='L', w=80.0, txt='+1-5555-5555', border=0)
    -pdf.set_xy(115.0, 69.0)
    -pdf.cell(ln=0, h=6.0, align='L', w=18.0, txt='Localidad:', border=0)
    -pdf.set_xy(133.0, 69.0)
    -pdf.cell(ln=0, h=6.0, align='L', w=42.0, txt='Springfield', border=0)
    -pdf.set_line_width(0.0)
    -pdf.line(15.0, 77.0, 185.0, 77.0)
    -pdf.set_xy(17.0, 80.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=15.0, txt='IVA:', border=0)
    -pdf.set_xy(35.0, 80.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=70.0, txt='Responsable', border=0)
    -pdf.set_xy(115.0, 80.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='CUIT:', border=0)
    -pdf.set_xy(135.0, 80.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=40.0, txt='10-12345678-9', border=0)
    -pdf.set_line_width(0.0)
    -pdf.line(15.0, 88.0, 185.0, 88.0)
    -pdf.set_xy(17.0, 90.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=48.0, txt='Fecha de Vencimiento Pago:', border=0)
    -pdf.set_xy(65.0, 90.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='23/07/1978', border=0)
    -pdf.set_xy(92.0, 90.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=43.0, txt='Per\xedodo Facturado', border=0)
    -pdf.set_xy(125.0, 90.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='01/01/2009', border=0)
    -pdf.set_xy(150.0, 90.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='31/01/2009', border=0)
    -pdf.set_line_width(0.0)
    -pdf.line(15.0, 95.0, 185.0, 95.0)
    -pdf.set_line_width(0.0)
    -pdf.line(155.0, 95.0, 155.0, 230.0)
    -pdf.set_xy(20.0, 97.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=125.0, txt='Descripci\xf3n', border=0)
    -pdf.set_xy(160.0, 97.0)
    -pdf.cell(ln=0, h=5.0, align='R', w=20.0, txt='Importe', border=0)
    -pdf.set_line_width(0.0)
    -pdf.line(15.0, 102.0, 185.0, 102.0)
    -pdf.set_xy(20.0, 103.0)
    -pdf.cell(ln=0, h=7.0, align='L', w=125.0, txt='Esto es una prueba y no es v\xe1lido como factura', border=0)
    -pdf.set_xy(160.0, 103.0)
    -pdf.cell(ln=0, h=7.0, align='R', w=20.0, txt='100,00', border=0)
    -pdf.set_line_width(0.0)
    -pdf.line(15.0, 230.0, 185.0, 230.0)
    -pdf.set_xy(20.0, 233.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=95.0, txt='CAE N\xba', border=0)
    -pdf.set_xy(45.0, 233.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=30.0, txt='01234567890', border=0)
    -pdf.set_font('arial', '', 12.0)
    -pdf.set_xy(105.0, 234.0)
    -pdf.cell(ln=0, h=9.0, align='R', w=45.0, txt='NETO GRAVADO:', border=0)
    -pdf.set_font('arial', 'B', 12.0)
    -pdf.set_xy(145.0, 234.0)
    -pdf.cell(ln=0, h=9.0, align='R', w=33.0, txt='100,00', border=0)
    -pdf.set_font('arial', '', 10.0)
    -pdf.set_xy(20.0, 238.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=95.0, txt='Fecha Vto. CAE:', border=0)
    -pdf.set_xy(55.0, 238.0)
    -pdf.cell(ln=0, h=5.0, align='L', w=30.0, txt='19/02/2009', border=0)
    -pdf.set_font('arial', '', 12.0)
    -pdf.set_xy(125.0, 241.0)
    -pdf.cell(ln=0, h=9.0, align='R', w=25.0, txt='IVA 21%:', border=0)
    -pdf.set_font('arial', 'B', 12.0)
    -pdf.set_xy(145.0, 241.0)
    -pdf.cell(ln=0, h=9.0, align='R', w=33.0, txt='21,00', border=0)
    -pdf.interleaved2of5('012345678905', 20.0, 243.5, w=0.75)
    -pdf.set_font('arial', 'B', 12.0)
    -pdf.set_xy(105.0, 251.0)
    -pdf.cell(ln=0, h=9.0, align='R', w=73.0, txt='121,00', border=0)
    -pdf.set_font('arial', '', 12.0)
    -pdf.set_xy(125.0, 251.0)
    -pdf.cell(ln=0, h=9.0, align='R', w=25.0, txt='Total:', border=0)
    -pdf.set_line_width(0.0)
    -pdf.rect(155.0, 252.0, 25.0, 7.0)
    -pdf.set_font('arial', '', 10.0)
    -pdf.set_xy(20.0, 253.0)
    -pdf.cell(ln=0, h=7.0, align='L', w=120.0, txt='012345678905', border=0)
    -pdf.output('/home/user/factura.pdf', 'F')
    -
    -os.system("/home/user/factura.pdf")
    +
    # -*- coding: iso-8859-1 -*-
    +#Actualizado 24/08/2012
    +import os
    +from fpdf import FPDF
    +
    +pdf = FPDF()
    +pdf.add_page(orientation='P')
    +pdf.set_font('arial', '', 13.0)
    +pdf.set_xy(105.0, 8.0)
    +pdf.cell(ln=0, h=22.0, align='C', w=75.0, txt='Comprobante de Ejemplo', border=0)
    +pdf.set_line_width(0.0)
    +pdf.rect(15.0, 15.0, 170.0, 245.0)
    +pdf.set_line_width(0.0)
    +pdf.rect(95.0, 15.0, 10.0, 10.0)
    +#descomentar para poner imagen de la serpiente
    +#pdf.image('serpiente.png', 20.0, 17.0, link='', type='', w=13.0, h=13.0)
    +pdf.set_font('arial', 'B', 16.0)
    +pdf.set_xy(95.0, 18.0)
    +pdf.cell(ln=0, h=2.0, align='C', w=10.0, txt='X', border=0)
    +pdf.set_font('arial', '', 8.0)
    +pdf.set_xy(105.0, 21.0)
    +pdf.cell(ln=0, h=4.0, align='C', w=75.0, txt='Original', border=0)
    +pdf.set_font('arial', 'B', 7.0)
    +pdf.set_xy(95.0, 21.5)
    +pdf.cell(ln=0, h=4.5, align='C', w=10.0, txt='COD.00', border=0)
    +pdf.set_line_width(0.0)
    +pdf.line(100.0, 25.0, 100.0, 57.0)
    +pdf.set_font('arial', 'B', 14.0)
    +pdf.set_xy(125.0, 25.5)
    +pdf.cell(ln=0, h=9.5, align='L', w=60.0, txt='00000001', border=0)
    +pdf.set_xy(115.0, 27.5)
    +pdf.cell(ln=0, h=5.5, align='L', w=10.0, txt='N\xba: ', border=0)
    +pdf.set_font('arial', 'B', 12.0)
    +pdf.set_xy(17.0, 32.5)
    +pdf.cell(ln=0, h=5.0, align='L', w=98.0, txt='EMPRESA', border=0)
    +pdf.set_font('arial', '', 12.0)
    +pdf.set_xy(115.0, 33.0)
    +pdf.cell(ln=0, h=7.0, align='L', w=60.0, txt='Fecha:', border=0)
    +pdf.set_xy(135.0, 33.0)
    +pdf.cell(ln=0, h=7.0, align='L', w=40.0, txt='19/02/2009', border=0)
    +pdf.set_line_width(0.0)
    +pdf.line(15.0, 57.0, 185.0, 57.0)
    +pdf.set_font('arial', '', 10.0)
    +pdf.set_xy(17.0, 59.0)
    +pdf.cell(ln=0, h=6.0, align='L', w=13.0, txt='Sr.(s):', border=0)
    +pdf.set_xy(35.0, 59.0)
    +pdf.cell(ln=0, h=6.0, align='L', w=140.0, txt='Mariano Reingart', border=0)
    +pdf.set_xy(17.0, 64.0)
    +pdf.cell(ln=0, h=6.0, align='L', w=18.0, txt='Domicilio:', border=0)
    +pdf.set_xy(35.0, 64.0)
    +pdf.cell(ln=0, h=6.0, align='L', w=125.0, txt='Siempreviva 12345', border=0)
    +pdf.set_xy(17.0, 69.0)
    +pdf.cell(ln=0, h=6.0, align='L', w=18.0, txt='Tel\xe9fono:', border=0)
    +pdf.set_xy(35.0, 69.0)
    +pdf.cell(ln=0, h=6.0, align='L', w=80.0, txt='+1-5555-5555', border=0)
    +pdf.set_xy(115.0, 69.0)
    +pdf.cell(ln=0, h=6.0, align='L', w=18.0, txt='Localidad:', border=0)
    +pdf.set_xy(133.0, 69.0)
    +pdf.cell(ln=0, h=6.0, align='L', w=42.0, txt='Springfield', border=0)
    +pdf.set_line_width(0.0)
    +pdf.line(15.0, 77.0, 185.0, 77.0)
    +pdf.set_xy(17.0, 80.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=15.0, txt='IVA:', border=0)
    +pdf.set_xy(35.0, 80.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=70.0, txt='Responsable', border=0)
    +pdf.set_xy(115.0, 80.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='CUIT:', border=0)
    +pdf.set_xy(135.0, 80.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=40.0, txt='10-12345678-9', border=0)
    +pdf.set_line_width(0.0)
    +pdf.line(15.0, 88.0, 185.0, 88.0)
    +pdf.set_xy(17.0, 90.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=48.0, txt='Fecha de Vencimiento Pago:', border=0)
    +pdf.set_xy(65.0, 90.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='23/07/1978', border=0)
    +pdf.set_xy(92.0, 90.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=43.0, txt='Per\xedodo Facturado', border=0)
    +pdf.set_xy(125.0, 90.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='01/01/2009', border=0)
    +pdf.set_xy(150.0, 90.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='31/01/2009', border=0)
    +pdf.set_line_width(0.0)
    +pdf.line(15.0, 95.0, 185.0, 95.0)
    +pdf.set_line_width(0.0)
    +pdf.line(155.0, 95.0, 155.0, 230.0)
    +pdf.set_xy(20.0, 97.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=125.0, txt='Descripci\xf3n', border=0)
    +pdf.set_xy(160.0, 97.0)
    +pdf.cell(ln=0, h=5.0, align='R', w=20.0, txt='Importe', border=0)
    +pdf.set_line_width(0.0)
    +pdf.line(15.0, 102.0, 185.0, 102.0)
    +pdf.set_xy(20.0, 103.0)
    +pdf.cell(ln=0, h=7.0, align='L', w=125.0, txt='Esto es una prueba y no es v\xe1lido como factura', border=0)
    +pdf.set_xy(160.0, 103.0)
    +pdf.cell(ln=0, h=7.0, align='R', w=20.0, txt='100,00', border=0)
    +pdf.set_line_width(0.0)
    +pdf.line(15.0, 230.0, 185.0, 230.0)
    +pdf.set_xy(20.0, 233.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=95.0, txt='CAE N\xba', border=0)
    +pdf.set_xy(45.0, 233.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=30.0, txt='01234567890', border=0)
    +pdf.set_font('arial', '', 12.0)
    +pdf.set_xy(105.0, 234.0)
    +pdf.cell(ln=0, h=9.0, align='R', w=45.0, txt='NETO GRAVADO:', border=0)
    +pdf.set_font('arial', 'B', 12.0)
    +pdf.set_xy(145.0, 234.0)
    +pdf.cell(ln=0, h=9.0, align='R', w=33.0, txt='100,00', border=0)
    +pdf.set_font('arial', '', 10.0)
    +pdf.set_xy(20.0, 238.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=95.0, txt='Fecha Vto. CAE:', border=0)
    +pdf.set_xy(55.0, 238.0)
    +pdf.cell(ln=0, h=5.0, align='L', w=30.0, txt='19/02/2009', border=0)
    +pdf.set_font('arial', '', 12.0)
    +pdf.set_xy(125.0, 241.0)
    +pdf.cell(ln=0, h=9.0, align='R', w=25.0, txt='IVA 21%:', border=0)
    +pdf.set_font('arial', 'B', 12.0)
    +pdf.set_xy(145.0, 241.0)
    +pdf.cell(ln=0, h=9.0, align='R', w=33.0, txt='21,00', border=0)
    +pdf.interleaved2of5('012345678905', 20.0, 243.5, w=0.75)
    +pdf.set_font('arial', 'B', 12.0)
    +pdf.set_xy(105.0, 251.0)
    +pdf.cell(ln=0, h=9.0, align='R', w=73.0, txt='121,00', border=0)
    +pdf.set_font('arial', '', 12.0)
    +pdf.set_xy(125.0, 251.0)
    +pdf.cell(ln=0, h=9.0, align='R', w=25.0, txt='Total:', border=0)
    +pdf.set_line_width(0.0)
    +pdf.rect(155.0, 252.0, 25.0, 7.0)
    +pdf.set_font('arial', '', 10.0)
    +pdf.set_xy(20.0, 253.0)
    +pdf.cell(ln=0, h=7.0, align='L', w=120.0, txt='012345678905', border=0)
    +pdf.output('/home/user/factura.pdf', 'F')
    +
    +os.system("/home/user/factura.pdf")
     

    Autor / Autores:

    MarianoReingart

    diff --git a/recetario/fun/minispaceinvaders/index.html b/recetario/fun/minispaceinvaders/index.html index aeedda092..163b4b0ee 100644 --- a/recetario/fun/minispaceinvaders/index.html +++ b/recetario/fun/minispaceinvaders/index.html @@ -26,7 +26,7 @@ La nave y el bicho se mueven solos de fo"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -92,123 +92,123 @@

    Mini Space Invaders

  • Se podría agregar manejo de eventos de teclado para manejar la nave y los disparos. Alguna idea usando módulo estándar de python?

  • En cuanto pueda pongo un videito.

  • -
    import random
    -import time
    -import os
    -
    -
    -ROWS = 14
    -COLS = 16
    -BULLET = '.'
    -SHOTS = []
    -SCREEN = []
    -EMPTY = ' '
    -EXPLOSION = '#'
    -SHIP = 'A'
    -BUG = 'W'
    -
    -
    -###############################################################################
    -# Funciones del mundo
    -###############################################################################
    -def crear_mapa():
    -    for row in range(0, ROWS):
    -        SCREEN.append([])
    -        for col in range(0, COLS):
    -            SCREEN[row].append(EMPTY)
    -
    -
    -def mostrar_mapa():
    -    for row in SCREEN:
    -        for col in row:
    -            print col,
    -        print
    -
    -
    -def mover_disparos():
    -    for disparo in SHOTS:
    -        SCREEN[disparo[0]][disparo[1]] = EMPTY
    -        if disparo[0] > 0:
    -            if SCREEN[disparo[0] - 1][disparo[1]] == BUG:
    -                SCREEN[disparo[0] - 1][disparo[1]] = EXPLOSION
    -                return False
    -            else:
    -                SCREEN[disparo[0] - 1][disparo[1]] = BULLET
    -                SHOTS.append((disparo[0] - 1, disparo[1]))
    -        SHOTS.remove(disparo)
    -    return True
    -
    -
    -def _mover_nave(direccion, nave, row):
    -    try:
    -        col = SCREEN[row].index(nave)
    -    except ValueError:
    -            col = 0
    -    SCREEN[row][col] = EMPTY
    -    next_col = col + (1 * direccion)
    -    if next_col > 15:
    -        next_col = 0
    -    SCREEN[row][next_col] = nave
    -
    -
    -def limpiar_pantalla():
    -    os.system(['clear', 'cls'][os.name == 'nt'])
    -
    -
    -###############################################################################
    -# Funciones para la nave
    -###############################################################################
    -def crear_nave():
    -    SCREEN[-1][random.randint(0, COLS - 1)] = SHIP
    -
    -
    -def mover_nave():
    -    if random.randint(0, 100) > 50:
    -        _mover_nave(-1, SHIP, -1)
    -    else:
    -        _mover_nave(1, SHIP, -1)
    -
    -
    -def disparar():
    -    if random.randint(0, 100) > 70:
    -        col = SCREEN[-1].index(SHIP)
    -        SCREEN[-2][col] = BULLET
    -        row = ROWS - 2
    -        SHOTS.append((row, col))
    -
    -
    -###############################################################################
    -# Funciones para el bicho
    -###############################################################################
    -def crear_bicho():
    -    SCREEN[0][random.randint(0, COLS - 1)] = BUG
    -
    -
    -def mover_bicho():
    -    if random.randint(0, 100) > 50:
    -        _mover_nave(-1, BUG, 0)
    -    else:
    -        _mover_nave(1, BUG, 0)
    -
    -
    -def jugar():
    -    crear_mapa()
    -    crear_nave()
    -    crear_bicho()
    -    while mover_disparos():
    -        mover_bicho()
    -        disparar()
    -        mover_nave()
    -        mostrar_mapa()
    -        time.sleep(0.2)
    -        limpiar_pantalla()
    -    limpiar_pantalla()
    -    mostrar_mapa()
    -    print "EL BICHO SE MURIO"
    -
    -
    -if __name__ == '__main__':
    -    jugar()
    +
    import random
    +import time
    +import os
    +
    +
    +ROWS = 14
    +COLS = 16
    +BULLET = '.'
    +SHOTS = []
    +SCREEN = []
    +EMPTY = ' '
    +EXPLOSION = '#'
    +SHIP = 'A'
    +BUG = 'W'
    +
    +
    +###############################################################################
    +# Funciones del mundo
    +###############################################################################
    +def crear_mapa():
    +    for row in range(0, ROWS):
    +        SCREEN.append([])
    +        for col in range(0, COLS):
    +            SCREEN[row].append(EMPTY)
    +
    +
    +def mostrar_mapa():
    +    for row in SCREEN:
    +        for col in row:
    +            print col,
    +        print
    +
    +
    +def mover_disparos():
    +    for disparo in SHOTS:
    +        SCREEN[disparo[0]][disparo[1]] = EMPTY
    +        if disparo[0] > 0:
    +            if SCREEN[disparo[0] - 1][disparo[1]] == BUG:
    +                SCREEN[disparo[0] - 1][disparo[1]] = EXPLOSION
    +                return False
    +            else:
    +                SCREEN[disparo[0] - 1][disparo[1]] = BULLET
    +                SHOTS.append((disparo[0] - 1, disparo[1]))
    +        SHOTS.remove(disparo)
    +    return True
    +
    +
    +def _mover_nave(direccion, nave, row):
    +    try:
    +        col = SCREEN[row].index(nave)
    +    except ValueError:
    +            col = 0
    +    SCREEN[row][col] = EMPTY
    +    next_col = col + (1 * direccion)
    +    if next_col > 15:
    +        next_col = 0
    +    SCREEN[row][next_col] = nave
    +
    +
    +def limpiar_pantalla():
    +    os.system(['clear', 'cls'][os.name == 'nt'])
    +
    +
    +###############################################################################
    +# Funciones para la nave
    +###############################################################################
    +def crear_nave():
    +    SCREEN[-1][random.randint(0, COLS - 1)] = SHIP
    +
    +
    +def mover_nave():
    +    if random.randint(0, 100) > 50:
    +        _mover_nave(-1, SHIP, -1)
    +    else:
    +        _mover_nave(1, SHIP, -1)
    +
    +
    +def disparar():
    +    if random.randint(0, 100) > 70:
    +        col = SCREEN[-1].index(SHIP)
    +        SCREEN[-2][col] = BULLET
    +        row = ROWS - 2
    +        SHOTS.append((row, col))
    +
    +
    +###############################################################################
    +# Funciones para el bicho
    +###############################################################################
    +def crear_bicho():
    +    SCREEN[0][random.randint(0, COLS - 1)] = BUG
    +
    +
    +def mover_bicho():
    +    if random.randint(0, 100) > 50:
    +        _mover_nave(-1, BUG, 0)
    +    else:
    +        _mover_nave(1, BUG, 0)
    +
    +
    +def jugar():
    +    crear_mapa()
    +    crear_nave()
    +    crear_bicho()
    +    while mover_disparos():
    +        mover_bicho()
    +        disparar()
    +        mover_nave()
    +        mostrar_mapa()
    +        time.sleep(0.2)
    +        limpiar_pantalla()
    +    limpiar_pantalla()
    +    mostrar_mapa()
    +    print "EL BICHO SE MURIO"
    +
    +
    +if __name__ == '__main__':
    +    jugar()
     
    diff --git a/recetario/fun/nadosincronizado/index.html b/recetario/fun/nadosincronizado/index.html index 1749b2f00..6584391ba 100644 --- a/recetario/fun/nadosincronizado/index.html +++ b/recetario/fun/nadosincronizado/index.html @@ -33,7 +33,7 @@ def figure(): fig = random.choice(ARM) + "o" + rand"> - +Ir al contenido principal @@ -67,12 +67,12 @@ - + @@ -93,29 +93,29 @@

    Nado Sincronizado

    Un generador de nado sincronizado

    http://marianoguerra.com.ar/random/nado.ogv

    -
    import sys
    -import time
    -import random
    -
    -ARM = ['\\', '_', '/', ' ']
    -
    -def figure():
    -    fig = random.choice(ARM) + "o" + random.choice(ARM)
    -    sys.stdout.write(fig)
    -    sys.stdout.flush()
    -
    -def erase():
    -    sys.stdout.write("\b\b\b")
    -    sys.stdout.flush()
    -
    -def dance():
    -    while True:
    -        figure()
    -        time.sleep(0.5)
    -        erase()
    -
    -if __name__ == '__main__':
    -    dance()
    +
    import sys
    +import time
    +import random
    +
    +ARM = ['\\', '_', '/', ' ']
    +
    +def figure():
    +    fig = random.choice(ARM) + "o" + random.choice(ARM)
    +    sys.stdout.write(fig)
    +    sys.stdout.flush()
    +
    +def erase():
    +    sys.stdout.write("\b\b\b")
    +    sys.stdout.flush()
    +
    +def dance():
    +    while True:
    +        figure()
    +        time.sleep(0.5)
    +        erase()
    +
    +if __name__ == '__main__':
    +    dance()
     
    diff --git a/recetario/fun/nadosincronizadodisco/index.html b/recetario/fun/nadosincronizadodisco/index.html index 31d431739..7f5fce640 100644 --- a/recetario/fun/nadosincronizadodisco/index.html +++ b/recetario/fun/nadosincronizadodisco/index.html @@ -31,7 +31,7 @@ def"> - +Ir al contenido principal @@ -65,12 +65,12 @@ - + @@ -90,32 +90,32 @@

    Nado Sincronizado

    Un generador de nado sincronizado con luces de colores usando colorama (sudo pip install colorama)

    -
    import sys
    -import time
    -import random
    -from colorama import init, Fore
    -ARM = ['\\', '_', '/', ' ']
    -
    -def figure():
    -    color = Fore.__dict__[random.choice(['BLACK', 'BLUE', 'CYAN',
    -        'GREEN', 'MAGENTA', 'RED', 'RESET', 'WHITE', 'YELLOW'])]
    -    fig = color + random.choice(ARM) + "o" + random.choice(ARM)
    -    sys.stdout.write(fig)
    -    sys.stdout.flush()
    -
    -def erase():
    -    sys.stdout.write("\b\b\b")
    -    sys.stdout.flush()
    -
    -def dance():
    -    init()
    -    while True:
    -        figure()
    -        time.sleep(0.5)
    -        erase()
    -
    -if __name__ == '__main__':
    -    dance()
    +
    import sys
    +import time
    +import random
    +from colorama import init, Fore
    +ARM = ['\\', '_', '/', ' ']
    +
    +def figure():
    +    color = Fore.__dict__[random.choice(['BLACK', 'BLUE', 'CYAN',
    +        'GREEN', 'MAGENTA', 'RED', 'RESET', 'WHITE', 'YELLOW'])]
    +    fig = color + random.choice(ARM) + "o" + random.choice(ARM)
    +    sys.stdout.write(fig)
    +    sys.stdout.flush()
    +
    +def erase():
    +    sys.stdout.write("\b\b\b")
    +    sys.stdout.flush()
    +
    +def dance():
    +    init()
    +    while True:
    +        figure()
    +        time.sleep(0.5)
    +        erase()
    +
    +if __name__ == '__main__':
    +    dance()
     
    diff --git a/recetario/gmailmail/index.html b/recetario/gmailmail/index.html index f1ca0eefa..cac5bc38b 100644 --- a/recetario/gmailmail/index.html +++ b/recetario/gmailmail/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -86,164 +86,164 @@

    Gmailmail

    Este script permite enviar emails a través de GMail. Los emails pueden tener texto plano, HTML y archivos adjuntos (todos opcionales).

    Nota: El script lo escribí originalmente en inglés. Debería entenderse, pero pienso traducirlo cuando tenga algo más de tiempo.

    Archivo: GmailMail.py

    -
    #!/usr/bin/env python
    -
    -# requires Python >= 2.5
    -import smtplib
    -from email.mime.multipart import MIMEMultipart
    -from email.mime.base import MIMEBase
    -from email.mime.text import MIMEText
    -from email.mime.audio import MIMEAudio
    -from email.mime.image import MIMEImage
    -from email.encoders import encode_base64
    -from mimetypes import guess_type
    -from os.path import basename
    -
    -class GmailMail():
    -    def __init__(self, gmail_user, gmail_pwd):
    -        """
    -        Prepares an instance with basic authentication
    -
    -        """
    -        self.gmail_user = gmail_user
    -        self.gmail_pwd = gmail_pwd
    -
    -    def getAttachment(self, path, charset='ASCII'):
    -        contentType, encoding = guess_type(path)
    -
    -        if contentType is None or encoding is not None:
    -            contentType = 'application/octet-stream'
    -
    -        mainType, subType = contentType.split('/', 1)
    -        _file = open(path, 'rb')
    -
    -        if mainType == 'text':
    -            attachment = MIMEText(_file.read(), subType, charset)
    -        elif mainType == 'message':
    -            attachment = email.message_from_file(_file)
    -        elif mainType == 'image':
    -            attachment = MIMEImage(_file.read(), _subType=subType)
    -        elif mainType == 'audio':
    -            attachment = MIMEAudio(_file.read(), _subType=subType)
    -        else:
    -            attachment = MIMEBase(mainType, subType)
    -            attachment.set_payload(_file.read())
    -            encode_base64(attachment)
    -
    -        _file.close()
    -
    -        attachment.add_header('Content-Disposition', 'attachment',
    -            filename=basename(path))
    -
    -        return attachment
    -
    -    def send(self, to, subject, text=u"", html=None, attachments=None, charset="iso-8859-15"):
    -        """
    -        Sends an email through Gmail using the authentication
    -        given to this instance.
    -
    -        If given, attachments must be a list of paths pointing
    -        to the files we want to include.
    -
    -        This script does not embed inline content (multipart/related)
    -
    -        """
    -        if charset in ['utf8','utf-8']: #bug?
    -            from email.charset import add_charset, SHORTEST
    -            add_charset('utf-8', SHORTEST, None, None)
    -
    -        if isinstance(text, unicode):
    -            text = text.encode(charset, 'replace')
    -
    -        if isinstance(html, unicode):
    -            html = html.encode(charset, 'replace')
    -
    -        if attachments is None:
    -            attachments = []
    -
    -        if text: plain_part = MIMEText(text, 'plain', charset)
    -        if html: html_part = MIMEText(html, 'html', charset)
    -
    -        is_alternative = html and text
    -        layers = []
    -        if attachments or is_alternative:
    -            msg = MIMEMultipart() #mixed
    -            msg.set_charset(charset)
    -            msg.preamble = 'This is a multi-part message in MIME format.'
    -            msg.epilogue = ''
    -            layers.append(msg)
    -
    -            if is_alternative:
    -                msgAlternative = MIMEMultipart('alternative')
    -                msg.attach(msgAlternative)
    -                layers.append(msgAlternative)
    -
    -            if text:
    -                layers[-1].attach(plain_part)
    -            if html:
    -                layers[-1].attach(html_part)
    -
    -        elif text:
    -            msg = plain_part
    -        else: #html only
    -            msg = html_part
    -
    -        for path in attachments:
    -            msg.attach(self.getAttachment(path, charset))
    -
    -        msg['From'] = self.gmail_user
    -        msg['To'] = to
    -        msg['Subject'] = subject
    -
    -        mailServer = smtplib.SMTP("smtp.gmail.com", 587)
    -        mailServer.ehlo()
    -        mailServer.starttls()
    -        mailServer.ehlo()
    -        mailServer.login(self.gmail_user, self.gmail_pwd)
    -        mailServer.sendmail(self.gmail_user, to, msg.as_string())
    -        # Should be mailServer.quit(), but that crashes...
    -        mailServer.close()
    +
    #!/usr/bin/env python
    +
    +# requires Python >= 2.5
    +import smtplib
    +from email.mime.multipart import MIMEMultipart
    +from email.mime.base import MIMEBase
    +from email.mime.text import MIMEText
    +from email.mime.audio import MIMEAudio
    +from email.mime.image import MIMEImage
    +from email.encoders import encode_base64
    +from mimetypes import guess_type
    +from os.path import basename
    +
    +class GmailMail():
    +    def __init__(self, gmail_user, gmail_pwd):
    +        """
    +        Prepares an instance with basic authentication
    +
    +        """
    +        self.gmail_user = gmail_user
    +        self.gmail_pwd = gmail_pwd
    +
    +    def getAttachment(self, path, charset='ASCII'):
    +        contentType, encoding = guess_type(path)
    +
    +        if contentType is None or encoding is not None:
    +            contentType = 'application/octet-stream'
    +
    +        mainType, subType = contentType.split('/', 1)
    +        _file = open(path, 'rb')
    +
    +        if mainType == 'text':
    +            attachment = MIMEText(_file.read(), subType, charset)
    +        elif mainType == 'message':
    +            attachment = email.message_from_file(_file)
    +        elif mainType == 'image':
    +            attachment = MIMEImage(_file.read(), _subType=subType)
    +        elif mainType == 'audio':
    +            attachment = MIMEAudio(_file.read(), _subType=subType)
    +        else:
    +            attachment = MIMEBase(mainType, subType)
    +            attachment.set_payload(_file.read())
    +            encode_base64(attachment)
    +
    +        _file.close()
    +
    +        attachment.add_header('Content-Disposition', 'attachment',
    +            filename=basename(path))
    +
    +        return attachment
    +
    +    def send(self, to, subject, text=u"", html=None, attachments=None, charset="iso-8859-15"):
    +        """
    +        Sends an email through Gmail using the authentication
    +        given to this instance.
    +
    +        If given, attachments must be a list of paths pointing
    +        to the files we want to include.
    +
    +        This script does not embed inline content (multipart/related)
    +
    +        """
    +        if charset in ['utf8','utf-8']: #bug?
    +            from email.charset import add_charset, SHORTEST
    +            add_charset('utf-8', SHORTEST, None, None)
    +
    +        if isinstance(text, unicode):
    +            text = text.encode(charset, 'replace')
    +
    +        if isinstance(html, unicode):
    +            html = html.encode(charset, 'replace')
    +
    +        if attachments is None:
    +            attachments = []
    +
    +        if text: plain_part = MIMEText(text, 'plain', charset)
    +        if html: html_part = MIMEText(html, 'html', charset)
    +
    +        is_alternative = html and text
    +        layers = []
    +        if attachments or is_alternative:
    +            msg = MIMEMultipart() #mixed
    +            msg.set_charset(charset)
    +            msg.preamble = 'This is a multi-part message in MIME format.'
    +            msg.epilogue = ''
    +            layers.append(msg)
    +
    +            if is_alternative:
    +                msgAlternative = MIMEMultipart('alternative')
    +                msg.attach(msgAlternative)
    +                layers.append(msgAlternative)
    +
    +            if text:
    +                layers[-1].attach(plain_part)
    +            if html:
    +                layers[-1].attach(html_part)
    +
    +        elif text:
    +            msg = plain_part
    +        else: #html only
    +            msg = html_part
    +
    +        for path in attachments:
    +            msg.attach(self.getAttachment(path, charset))
    +
    +        msg['From'] = self.gmail_user
    +        msg['To'] = to
    +        msg['Subject'] = subject
    +
    +        mailServer = smtplib.SMTP("smtp.gmail.com", 587)
    +        mailServer.ehlo()
    +        mailServer.starttls()
    +        mailServer.ehlo()
    +        mailServer.login(self.gmail_user, self.gmail_pwd)
    +        mailServer.sendmail(self.gmail_user, to, msg.as_string())
    +        # Should be mailServer.quit(), but that crashes...
    +        mailServer.close()
     

    Algunos tests (ejemplos, casos de uso):

    Archivo: GmailMail_tests.py

    -
    # -*- coding: utf-8 -*-
    -
    -from GmailMail import GmailMail
    -from urllib2 import urlopen
    -
    -text = u"""\
    -Éste es el contenido en modo texto plano
    -Tenemos acentos y eñes.
    -
    -"""
    -url = "http://python.com.ar/moin"
    -html = urlopen(url).read()
    -
    -user = 'XXXXXX@gmail.com' # mi usuario de GMail
    -pwd  = '********'         # mi contraseña de GMail
    -
    -m = GmailMail(user, pwd)
    -
    -print "mandando texto plano solamente"
    -m.send(user, u'prueba de sólo texto', text)
    -
    -print "mandando html solamente"
    -m.send(user, u'prueba con sólo html', html=html)
    -
    -print "mandando texto plano y html (sin attachments)"
    -m.send(user, u'prueba con texto plano y html (sin attachments)', text, html)
    -
    -print "mandando texto plano y attachments"
    -m.send(user, u'prueba con texto plano y attachments', text, attachments=['GmailMail.py'])
    -
    -print "mandando html y attachments"
    -m.send(user, u'prueba con html y attachments', html=html, attachments=['GmailMail.py'])
    -
    -print "mandando attachments solamente"
    -m.send(user, u'prueba con attachments solamente', attachments=['GmailMail.py'])
    -
    -print "mandando todo"
    -m.send(user, u'prueba con todo', text, html, attachments=['GmailMail.py'])
    +
    # -*- coding: utf-8 -*-
    +
    +from GmailMail import GmailMail
    +from urllib2 import urlopen
    +
    +text = u"""\
    +Éste es el contenido en modo texto plano
    +Tenemos acentos y eñes.
    +
    +"""
    +url = "http://python.com.ar/moin"
    +html = urlopen(url).read()
    +
    +user = 'XXXXXX@gmail.com' # mi usuario de GMail
    +pwd  = '********'         # mi contraseña de GMail
    +
    +m = GmailMail(user, pwd)
    +
    +print "mandando texto plano solamente"
    +m.send(user, u'prueba de sólo texto', text)
    +
    +print "mandando html solamente"
    +m.send(user, u'prueba con sólo html', html=html)
    +
    +print "mandando texto plano y html (sin attachments)"
    +m.send(user, u'prueba con texto plano y html (sin attachments)', text, html)
    +
    +print "mandando texto plano y attachments"
    +m.send(user, u'prueba con texto plano y attachments', text, attachments=['GmailMail.py'])
    +
    +print "mandando html y attachments"
    +m.send(user, u'prueba con html y attachments', html=html, attachments=['GmailMail.py'])
    +
    +print "mandando attachments solamente"
    +m.send(user, u'prueba con attachments solamente', attachments=['GmailMail.py'])
    +
    +print "mandando todo"
    +m.send(user, u'prueba con todo', text, html, attachments=['GmailMail.py'])
     

    Referencias (que recuerdo):

      diff --git a/recetario/gtkontk/index.html b/recetario/gtkontk/index.html index df8314e81..8de06e170 100644 --- a/recetario/gtkontk/index.html +++ b/recetario/gtkontk/index.html @@ -26,7 +26,7 @@ Foto de Pantalla: De fondo Gedit en Ubuntu, usando el tema Ambiance, arriba una ventana con similar tema pero en TK"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -91,219 +91,219 @@

    Gtk On Tk

    El codigo de este ejemplo esta mas abajo (la foto no esta editada, no hay truco, funciona en KDE, o inclusive lo he hecho funcionar sin GTK instalado).

    /images/GTKonTK/gtk-on-tk-hack.jpg

    El Código para hacer GTK en TK:

    -
    #
    -#!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -#   colour.py
    -#
    -import os
    -import sys
    -import gtk
    -try:
    -    import gconf
    -    NOGCONF = False
    -except:
    -    NOGCONF = True
    -
    -__all__ = ["_get_color_scheme", "_get_color_scheme_list", "get_color_scheme_item", "string_to_gdkColour", "string_to_rgba", "get_Gtk_Theme_Name", "get_Gtk_Theme_Path"]
    -
    -def _get_color_scheme():
    -    gtkSet = gtk.settings_get_default()
    -    return gtkSet.get_property('gtk-color-scheme')
    -
    -def _get_color_scheme_list():
    -    gtkSch = _get_color_scheme()
    -    itemList = []
    -    for line in gtkSch.splitlines():
    -        itemList.append(line.split(":")[0])
    -    return itemList
    -
    -def get_color_scheme_item(colorName):
    -    gtkSch = _get_color_scheme()
    -    findLine = gtkSch[gtkSch.find(colorName):].splitlines()[0]
    -    c = findLine.replace(colorName+":", "").strip()
    -    #print colorName, "=", c
    -    c = c.replace("#", "")
    -    if len(c) == 12:
    -        #4 chars, r g b
    -        rgba = [c[0:4], c[4:8], c[8:12], ""]
    -    colourFound = '#'
    -    for set in rgba:
    -       colourFound = "".join([colourFound, set[:2].upper()])
    -    if len(colourFound) == 0:
    -        raise error
    -        return None
    -    else:
    -        return colourFound
    -
    -def incHex(c, times=1):
    -    import string
    -    c = c.replace("#", "")
    -    c = c.upper()
    -    hexString = '0123456789ABCDEF'
    -    if times > 0:
    -        if times > 16: times = 16
    -        hexString = hexString[times:]
    -        hexString = hexString.ljust(16, 'F')
    -    else:
    -        if times < -16: times = -16
    -        hexString = hexString[:times]
    -        hexString = hexString.rjust(16, '0')
    -    trans = string.maketrans('0123456789ABCDEF', hexString)
    -    ic = c.translate(trans)
    -    ic = "".join(['#', ic])
    -    return ic
    -
    -def string_to_gdkColor(c):
    -    if c[0] != '#': c = "".join(['#',c])
    -    while len(c) not in [4, 7, 10, 13]:
    -        c = c[0:len(c)-1]
    -    return gtk.gdk.color_parse(c)
    -
    -def rgba_to_string(r, g, b, a=None):
    -    if (a==None):
    -        a = 1
    -    hr, hg, hb, ha = [hex(min(int(n*255), 255))[2:] for n in(r, g, b, a)]
    -    hList = ['#']
    -    for n in (hr, hg, hb, ha):
    -        #print n
    -        hList.append(n.rjust(2, '0').upper())
    -    hr = hr.rjust(2, '0')
    -    hg = hg.rjust(2, '0')
    -    hb = hb.rjust(2, '0')
    -    ha = ha.rjust(2, '0')
    -    return "".join(hList)
    -
    -def string_to_rgb(c):
    -    r, g, b, a = (string_to_rgba(c))
    -    return r, g, b
    -
    -def string_to_rgba(c):
    -    c = c.replace("#", "")
    -    if len(c) == 12:
    -        #4 chars, r g b
    -        r, g, b = (c[0:4], c[4:8], c[8:12])
    -        r, g, b = [int(n, 16)/65535.0 for n in(r, g, b)]
    -        a = 1
    -    elif len(c) == 8:
    -        #2 chars, r g b a
    -        r, g, b, a = (c[0:2], c[2:4], c[4:6], c[6:8])
    -        r, g, b, a = [int(n, 16)/255.0 for n in(r, g, b, a)]
    -    elif len(c) == 6:
    -        #2 chars, r g b
    -        r, g, b = (c[0:2], c[2:4], c[4:6])
    -        r, g, b = [int(n, 16)/255.0 for n in(r, g, b)]
    -        a = 1
    -    return r, g, b, a
    -
    -def get_Gtk_Theme_Name():
    -    if NOGCONF:
    -        try:
    -            gtkrc = open(os.path.expanduser('~/.gtkrc-2.0'))
    -        except:
    -            gtkrc = open(os.path.expanduser('~/.gtkrc-2.0-kde4'))
    -        for line in gtkrc:
    -            if 'include' in line:
    -                themePath = line.split("\"")[1]
    -                gtkTheme = themePath.split("/")[-3]
    -    else:
    -        client = gconf.client_get_default()
    -        gtkTheme = client.get_string('/desktop/gnome/interface/gtk_theme')
    -    return gtkTheme
    -
    -def get_Gtk_Theme_Path(gtkTheme=None):
    -    if gtkTheme == None:
    -        gtkTheme = get_Gtk_Theme_Name()
    -    localThemePath = "".join(["~/.themes/", gtkTheme, "/gtk-2.0/gtkrc"])
    -    localThemePath = os.path.expanduser(localThemePath)
    -    globalThemePath = "".join(["/usr/share/themes/", gtkTheme, "/gtk-2.0/gtkrc"])
    -    if os.path.exists(localThemePath):
    -        ThemePath = localThemePath
    -    elif os.path.exists(globalThemePath):
    -        ThemePath = globalThemePath
    -    else:
    -        ThemePath = None
    -
    -    if ThemePath:
    -        return ThemePath
    -    else:
    -        raise NameError
    -
    -if __name__ == "__main__":
    -    import random
    -    print "COLOUR TEST HARNESS"
    -    print get_Gtk_Theme_Name()
    -    print _get_color_scheme()
    -    colourList = ['030A16FF', '#090E1BDD', '#9595b0b0dbdb', '1414f3f3a8a8']
    -    colourList.append(get_color_scheme_item(_get_color_scheme_list()[random.randint(0, len(_get_color_scheme_list())-1)]))
    -    for cc in colourList:
    -        break
    -        print "Colour String ", cc
    -        print "gdkColour     ", string_to_gdkColor(cc)
    -        print "rgba          ", zip(string_to_rgba(cc))
    -    print "rgba to string", rgba_to_string(0, 0.5, 1, 0.3)
    -    print "inc ", incHex(rgba_to_string(0, 0.5, 1, 0.3))
    -    print get_color_scheme_item('selected_bg_color')
    +
    #
    +#!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +#   colour.py
    +#
    +import os
    +import sys
    +import gtk
    +try:
    +    import gconf
    +    NOGCONF = False
    +except:
    +    NOGCONF = True
    +
    +__all__ = ["_get_color_scheme", "_get_color_scheme_list", "get_color_scheme_item", "string_to_gdkColour", "string_to_rgba", "get_Gtk_Theme_Name", "get_Gtk_Theme_Path"]
    +
    +def _get_color_scheme():
    +    gtkSet = gtk.settings_get_default()
    +    return gtkSet.get_property('gtk-color-scheme')
    +
    +def _get_color_scheme_list():
    +    gtkSch = _get_color_scheme()
    +    itemList = []
    +    for line in gtkSch.splitlines():
    +        itemList.append(line.split(":")[0])
    +    return itemList
    +
    +def get_color_scheme_item(colorName):
    +    gtkSch = _get_color_scheme()
    +    findLine = gtkSch[gtkSch.find(colorName):].splitlines()[0]
    +    c = findLine.replace(colorName+":", "").strip()
    +    #print colorName, "=", c
    +    c = c.replace("#", "")
    +    if len(c) == 12:
    +        #4 chars, r g b
    +        rgba = [c[0:4], c[4:8], c[8:12], ""]
    +    colourFound = '#'
    +    for set in rgba:
    +       colourFound = "".join([colourFound, set[:2].upper()])
    +    if len(colourFound) == 0:
    +        raise error
    +        return None
    +    else:
    +        return colourFound
    +
    +def incHex(c, times=1):
    +    import string
    +    c = c.replace("#", "")
    +    c = c.upper()
    +    hexString = '0123456789ABCDEF'
    +    if times > 0:
    +        if times > 16: times = 16
    +        hexString = hexString[times:]
    +        hexString = hexString.ljust(16, 'F')
    +    else:
    +        if times < -16: times = -16
    +        hexString = hexString[:times]
    +        hexString = hexString.rjust(16, '0')
    +    trans = string.maketrans('0123456789ABCDEF', hexString)
    +    ic = c.translate(trans)
    +    ic = "".join(['#', ic])
    +    return ic
    +
    +def string_to_gdkColor(c):
    +    if c[0] != '#': c = "".join(['#',c])
    +    while len(c) not in [4, 7, 10, 13]:
    +        c = c[0:len(c)-1]
    +    return gtk.gdk.color_parse(c)
    +
    +def rgba_to_string(r, g, b, a=None):
    +    if (a==None):
    +        a = 1
    +    hr, hg, hb, ha = [hex(min(int(n*255), 255))[2:] for n in(r, g, b, a)]
    +    hList = ['#']
    +    for n in (hr, hg, hb, ha):
    +        #print n
    +        hList.append(n.rjust(2, '0').upper())
    +    hr = hr.rjust(2, '0')
    +    hg = hg.rjust(2, '0')
    +    hb = hb.rjust(2, '0')
    +    ha = ha.rjust(2, '0')
    +    return "".join(hList)
    +
    +def string_to_rgb(c):
    +    r, g, b, a = (string_to_rgba(c))
    +    return r, g, b
    +
    +def string_to_rgba(c):
    +    c = c.replace("#", "")
    +    if len(c) == 12:
    +        #4 chars, r g b
    +        r, g, b = (c[0:4], c[4:8], c[8:12])
    +        r, g, b = [int(n, 16)/65535.0 for n in(r, g, b)]
    +        a = 1
    +    elif len(c) == 8:
    +        #2 chars, r g b a
    +        r, g, b, a = (c[0:2], c[2:4], c[4:6], c[6:8])
    +        r, g, b, a = [int(n, 16)/255.0 for n in(r, g, b, a)]
    +    elif len(c) == 6:
    +        #2 chars, r g b
    +        r, g, b = (c[0:2], c[2:4], c[4:6])
    +        r, g, b = [int(n, 16)/255.0 for n in(r, g, b)]
    +        a = 1
    +    return r, g, b, a
    +
    +def get_Gtk_Theme_Name():
    +    if NOGCONF:
    +        try:
    +            gtkrc = open(os.path.expanduser('~/.gtkrc-2.0'))
    +        except:
    +            gtkrc = open(os.path.expanduser('~/.gtkrc-2.0-kde4'))
    +        for line in gtkrc:
    +            if 'include' in line:
    +                themePath = line.split("\"")[1]
    +                gtkTheme = themePath.split("/")[-3]
    +    else:
    +        client = gconf.client_get_default()
    +        gtkTheme = client.get_string('/desktop/gnome/interface/gtk_theme')
    +    return gtkTheme
    +
    +def get_Gtk_Theme_Path(gtkTheme=None):
    +    if gtkTheme == None:
    +        gtkTheme = get_Gtk_Theme_Name()
    +    localThemePath = "".join(["~/.themes/", gtkTheme, "/gtk-2.0/gtkrc"])
    +    localThemePath = os.path.expanduser(localThemePath)
    +    globalThemePath = "".join(["/usr/share/themes/", gtkTheme, "/gtk-2.0/gtkrc"])
    +    if os.path.exists(localThemePath):
    +        ThemePath = localThemePath
    +    elif os.path.exists(globalThemePath):
    +        ThemePath = globalThemePath
    +    else:
    +        ThemePath = None
    +
    +    if ThemePath:
    +        return ThemePath
    +    else:
    +        raise NameError
    +
    +if __name__ == "__main__":
    +    import random
    +    print "COLOUR TEST HARNESS"
    +    print get_Gtk_Theme_Name()
    +    print _get_color_scheme()
    +    colourList = ['030A16FF', '#090E1BDD', '#9595b0b0dbdb', '1414f3f3a8a8']
    +    colourList.append(get_color_scheme_item(_get_color_scheme_list()[random.randint(0, len(_get_color_scheme_list())-1)]))
    +    for cc in colourList:
    +        break
    +        print "Colour String ", cc
    +        print "gdkColour     ", string_to_gdkColor(cc)
    +        print "rgba          ", zip(string_to_rgba(cc))
    +    print "rgba to string", rgba_to_string(0, 0.5, 1, 0.3)
    +    print "inc ", incHex(rgba_to_string(0, 0.5, 1, 0.3))
    +    print get_color_scheme_item('selected_bg_color')
     

    Ejemplo:

    Descripcion: Crea 2 ventanas pequeñas iguales, una tratara de imitar el tema de GTK, la otra se mostrara como es por defecto.

    (el ejemplo funciona en Ubuntu, que es lo que yo uso, usa el codigo de arriba, lejos de estar bien hecho, pero sirve de ejemplo).

    -
    #
    -#!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -#import this
    -#import antigravity
    -import colour  # <-------Aca esta la magia
    -import tkFont
    -from Tkinter import *
    -#
    -root = Tk()
    -root.title('GTK Themes on TK: Demo')
    -root.wm_attributes("-alpha", 1)
    -root.focus()
    -root.resizable(0, 0)
    -# Muestra informacion
    -print " GTK-On-TK Theme Hack:"
    -print " I will try to mimic: "+colour.get_Gtk_Theme_Name()+" GTK Theme"
    -print " By Parsing the file: "+colour.get_Gtk_Theme_Path()
    -print " This is not perfect, if you are on KDE install QTCurve... "
    -# Menubar con GTK
    -menubar = Menu(root, bd=0, relief=FLAT, fg=str(colour.get_color_scheme_item('base_color')), bg=str(colour.get_color_scheme_item('text_color')), activebackground=str(colour.get_color_scheme_item('selected_bg_color')), activeforeground=str(colour.get_color_scheme_item('text_color')))
    -filemenu = Menu(menubar, tearoff=0, bd=0, relief=FLAT, fg=str(colour.get_color_scheme_item('base_color')), bg=str(colour.get_color_scheme_item('text_color')), activebackground=str(colour.get_color_scheme_item('selected_bg_color')), activeforeground=str(colour.get_color_scheme_item('text_color')))
    -filemenu.add_command(label="Nuevo", state='disabled')
    -filemenu.add_separator()
    -filemenu.add_command(label="Cerrar ✗", command= lambda: root.destroy())
    -menubar.add_cascade(label="Archivo", menu=filemenu)
    -root.config(menu=menubar)
    -# GUI con GTK
    -root.config(bg=str(colour.get_color_scheme_item('base_color')))
    -labl1 = Label(root, text="Soy una ventana con Tema GTK", font=("Times", 12, 'bold'), bd=0, relief=FLAT, bg=str(colour.get_color_scheme_item('base_color')), fg=str(colour.get_color_scheme_item('text_color')), activebackground=str(colour.get_color_scheme_item('selected_bg_color')), activeforeground=str(colour.get_color_scheme_item('text_color')))
    -labl1.pack(side=TOP, expand='YES', fill='x', pady=10, padx=20)
    -button = Button(root, text="Soy Linda!", fg=str(colour.get_color_scheme_item('text_color')), bd=0, relief=FLAT, bg=str(colour.get_color_scheme_item('base_color')),  activebackground=str(colour.get_color_scheme_item('selected_bg_color')), activeforeground=str(colour.get_color_scheme_item('text_color')))
    -button.pack(side=BOTTOM, pady=10, padx=10)
    -# la misma GUI pero como es por defecto
    -toplevel = Toplevel()
    -menubarz = Menu(toplevel)
    -filemenuz = Menu(toplevel, tearoff=0)
    -filemenuz.add_command(label="Nuevo", state='disabled')
    -filemenuz.add_separator()
    -filemenuz.add_command(label="Cerrar ✗", command= lambda: root.destroy())
    -menubarz.add_cascade(label="Archivo", menu=filemenuz)
    -toplevel.config(menu=menubarz)
    -labl2 = Label(toplevel, text="Soy una ventana SIN Tema GTK")
    -labl2.pack(side=TOP, expand='YES', fill='x', pady=10, padx=20)
    -button2 = Button(toplevel, text="Soy Fea!")
    -button2.pack(side=BOTTOM, pady=10, padx=10)
    -# Le pongo fuente de Ubuntu (se puede omitir)
    -menubar.config(font=("ubuntu", 10, "normal", "roman") )
    -labl1.config(font=("ubuntu", 10, "bold", "roman") )
    -filemenu.config(font=("ubuntu", 10, "normal", "roman") )
    -button.config(font=("ubuntu", 10, "bold", "roman") )
    -#
    -root.mainloop()
    +
    #
    +#!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +#import this
    +#import antigravity
    +import colour  # <-------Aca esta la magia
    +import tkFont
    +from Tkinter import *
    +#
    +root = Tk()
    +root.title('GTK Themes on TK: Demo')
    +root.wm_attributes("-alpha", 1)
    +root.focus()
    +root.resizable(0, 0)
    +# Muestra informacion
    +print " GTK-On-TK Theme Hack:"
    +print " I will try to mimic: "+colour.get_Gtk_Theme_Name()+" GTK Theme"
    +print " By Parsing the file: "+colour.get_Gtk_Theme_Path()
    +print " This is not perfect, if you are on KDE install QTCurve... "
    +# Menubar con GTK
    +menubar = Menu(root, bd=0, relief=FLAT, fg=str(colour.get_color_scheme_item('base_color')), bg=str(colour.get_color_scheme_item('text_color')), activebackground=str(colour.get_color_scheme_item('selected_bg_color')), activeforeground=str(colour.get_color_scheme_item('text_color')))
    +filemenu = Menu(menubar, tearoff=0, bd=0, relief=FLAT, fg=str(colour.get_color_scheme_item('base_color')), bg=str(colour.get_color_scheme_item('text_color')), activebackground=str(colour.get_color_scheme_item('selected_bg_color')), activeforeground=str(colour.get_color_scheme_item('text_color')))
    +filemenu.add_command(label="Nuevo", state='disabled')
    +filemenu.add_separator()
    +filemenu.add_command(label="Cerrar ✗", command= lambda: root.destroy())
    +menubar.add_cascade(label="Archivo", menu=filemenu)
    +root.config(menu=menubar)
    +# GUI con GTK
    +root.config(bg=str(colour.get_color_scheme_item('base_color')))
    +labl1 = Label(root, text="Soy una ventana con Tema GTK", font=("Times", 12, 'bold'), bd=0, relief=FLAT, bg=str(colour.get_color_scheme_item('base_color')), fg=str(colour.get_color_scheme_item('text_color')), activebackground=str(colour.get_color_scheme_item('selected_bg_color')), activeforeground=str(colour.get_color_scheme_item('text_color')))
    +labl1.pack(side=TOP, expand='YES', fill='x', pady=10, padx=20)
    +button = Button(root, text="Soy Linda!", fg=str(colour.get_color_scheme_item('text_color')), bd=0, relief=FLAT, bg=str(colour.get_color_scheme_item('base_color')),  activebackground=str(colour.get_color_scheme_item('selected_bg_color')), activeforeground=str(colour.get_color_scheme_item('text_color')))
    +button.pack(side=BOTTOM, pady=10, padx=10)
    +# la misma GUI pero como es por defecto
    +toplevel = Toplevel()
    +menubarz = Menu(toplevel)
    +filemenuz = Menu(toplevel, tearoff=0)
    +filemenuz.add_command(label="Nuevo", state='disabled')
    +filemenuz.add_separator()
    +filemenuz.add_command(label="Cerrar ✗", command= lambda: root.destroy())
    +menubarz.add_cascade(label="Archivo", menu=filemenuz)
    +toplevel.config(menu=menubarz)
    +labl2 = Label(toplevel, text="Soy una ventana SIN Tema GTK")
    +labl2.pack(side=TOP, expand='YES', fill='x', pady=10, padx=20)
    +button2 = Button(toplevel, text="Soy Fea!")
    +button2.pack(side=BOTTOM, pady=10, padx=10)
    +# Le pongo fuente de Ubuntu (se puede omitir)
    +menubar.config(font=("ubuntu", 10, "normal", "roman") )
    +labl1.config(font=("ubuntu", 10, "bold", "roman") )
    +filemenu.config(font=("ubuntu", 10, "normal", "roman") )
    +button.config(font=("ubuntu", 10, "bold", "roman") )
    +#
    +root.mainloop()
     

    Comentario personal:

    Es más bonito que TTK 🙂. Como sea, la idea es aprovechar que en Linux TODO es un archivo, la magia esta en parsear.

    @@ -320,425 +320,425 @@

    Gtk On Tk

  • No funciona con ttk.

  • Probado con python 2.6 y PyGtk 2.17

    -
    # -*- coding: utf-8 -*-
    -
    -#
    -# colour.py
    -#
    -
    -__all__ = ['apply_gtk_theme']
    -
    -import tkFont as tkfont
    -
    -HAS_GTK = False
    -try:
    -    import gtk
    -    HAS_GTK = True
    -except:
    -    pass
    -
    -def _get_color_scheme():
    -    gtkSet = gtk.settings_get_default()
    -    return gtkSet.get_property('gtk-color-scheme')
    -
    -def get_color_scheme_item(colorName):
    -    gtkSch = _get_color_scheme()
    -    findLine = ''
    -    for l in gtkSch.splitlines():
    -        if l.startswith(colorName):
    -            findLine = l
    -            break
    -    c = findLine.replace(colorName+":", "").strip()
    -    c = c.replace("#", "")
    -    rgba = []
    -    if len(c) == 12:
    -        rgba = [c[0:4], c[4:8], c[8:12], ""]
    -    colourFound = '#'
    -    for set in rgba:
    -       colourFound = "".join([colourFound, set[:2].upper()])
    -    if len(colourFound) == 0:
    -        raise error
    -        return None
    -    else:
    -        return colourFound
    -
    -
    -tk_fonts = {}
    -tk_font_families= None
    -
    -def get_tk_font(font_desc):
    -    """Crea una fuente tk"""
    -
    -    global tk_font_families
    -    global tk_fonts
    -
    -    if tk_font_families is None:
    -        tk_font_families = tkfont.families()
    -    font = None
    -    if font_desc in tk_fonts:
    -        font = tk_fonts[font_desc]
    -    else:
    -        family = 'Helvetica'
    -        for x in tk_font_families:
    -            if x in font_desc:
    -                family = x
    -        s = font_desc.split()
    -        size = s[-1]
    -        lower = font_desc.lower()
    -        weight = 'normal'
    -        slant = 'roman'
    -        if 'bold' in lower:
    -            weight = 'bold'
    -        if 'italic' in lower:
    -            slant='italic'
    -        #print '%s, %s, %s, %s' % (family, weight, slant, size)
    -        f = tkfont.Font(family=family, size=size, weight=weight, slant=slant )
    -        tk_fonts[font_desc]= font = f
    -    return font
    -
    -
    -#gtk_states = [gtk.STATE_NORMAL, gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE, gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE]
    -
    -def get_tk_styles():
    -    """Toma los estilos de Gtk y los "traduce" a estilos tk."""
    -    tk_styles = {}
    -
    -    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    -        '*<GtkLabel>*', '<GtkLabel>', gtk.Label)
    -    c = {
    -        'foreground': str(style.text[gtk.STATE_NORMAL]),
    -        'background': str(style.bg[gtk.STATE_NORMAL]),
    -        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    -        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    -        'font': get_tk_font(str(style.font_desc)),
    -    }
    -    tk_styles['Label'] = label = c
    -    tk_styles['Message'] = c
    -
    -    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    -        '*<GtkEntry>*', 'GtkEntry', gtk.Entry)
    -    c = {
    -        'foreground': str(style.text[gtk.STATE_NORMAL]),
    -        'background': get_color_scheme_item('base_color'),
    -        'selectForeground': str(style.text[gtk.STATE_SELECTED]),
    -        'selectBackground': str(style.bg[gtk.STATE_SELECTED]),
    -        'activeForeground': str(style.bg[gtk.STATE_NORMAL]),
    -        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    -        'font': get_tk_font(str(style.font_desc)),
    -    }
    -    tk_styles['Entry'] = c
    -    tk_styles['Text'] = c
    -    tk_styles['Spinbox'] = c
    -
    -    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    -        '*<GtkMenuBar>*', 'GtkMenuBar', gtk.MenuBar)
    -    c = {
    -        'foreground': str(style.text[gtk.STATE_NORMAL]),
    -        'background': str(style.bg[gtk.STATE_NORMAL]),
    -        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    -        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    -        'font': get_tk_font(str(style.font_desc)),
    -    }
    -    tk_styles['Menu'] = c
    -
    -    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    -        '*<GtkButton>*', 'GtkButton', gtk.Button)
    -    c = {
    -        'foreground': str(style.text[gtk.STATE_NORMAL]),
    -        'background': str(style.bg[gtk.STATE_NORMAL]),
    -        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    -        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    -        'font': get_tk_font(str(style.font_desc)),
    -    }
    -    tk_styles['Button'] = c
    -    tk_styles['OptionMenu'] = c
    -
    -    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    -        '*<GtkCheck>*', 'GtkCheck', gtk.CheckButton)
    -    c = {
    -        'foreground': label['foreground'],
    -        'background': label['background'],
    -        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    -        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    -        'selectColor': str(style.bg[gtk.STATE_SELECTED]),
    -        'font': get_tk_font(str(style.font_desc)),
    -    }
    -    tk_styles['Checkbutton'] = c
    -
    -    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    -        '*<GtkRadio>*', 'GtkRadio', gtk.RadioButton)
    -    c = {
    -        'foreground': label['foreground'],
    -        'background': label['background'],
    -        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    -        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    -        'selectColor': str(style.bg[gtk.STATE_SELECTED]),
    -        'font': get_tk_font(str(style.font_desc)),
    -    }
    -    tk_styles['Radiobutton'] = c
    -
    -    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    -        '*<GtkList>*', 'GtkList', gtk.List)
    -    c = {
    -        'foreground': str(style.text[gtk.STATE_NORMAL]),
    -        'background': str(style.bg[gtk.STATE_NORMAL]),
    -        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    -        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    -        'selectForeground': str(style.text[gtk.STATE_SELECTED]),
    -        'selectBackground': str(style.bg[gtk.STATE_SELECTED]),
    -        'font': get_tk_font(str(style.font_desc)),
    -    }
    -    tk_styles['Listbox'] = c
    -
    -    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    -        '*<GtkScrollbar>*', 'GtkScrollbar', gtk.Scrollbar)
    -    c = {
    -        'foreground': str(style.text[gtk.STATE_NORMAL]),
    -        'background': str(style.bg[gtk.STATE_NORMAL]),
    -        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    -        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    -        'troughColor': str(style.bg[gtk.STATE_ACTIVE]),
    -        'font': get_tk_font(str(style.font_desc)),
    -    }
    -    tk_styles['Scrollbar'] = c
    -    tk_styles['Scale'] = c
    -
    -    return tk_styles
    -
    -
    -def apply_gtk_theme_real(w):
    -    tk_style = get_tk_styles()
    -    bg_color = get_color_scheme_item('bg_color')
    -    selected_bg_color = get_color_scheme_item('selected_bg_color')
    -    patterns = (
    -        ('*Frame*background', bg_color),
    -
    -        ('*Menu*foreground', tk_style['Menu']['foreground']),
    -        ('*Menu*background', tk_style['Menu']['background']),
    -        ('*Menu*activeBackground', tk_style['Menu']['activeBackground']),
    -        ('*Menu*activeForeground', tk_style['Menu']['activeForeground']),
    -        ('*Menu*font', tk_style['Menu']['font']),
    -        ('*Menu*highlightBackground', bg_color),
    -        ('*Menu*highlightColor', selected_bg_color),
    -
    -        ('*Button*foreground', tk_style['Button']['foreground']),
    -        ('*Button*background', tk_style['Button']['background']),
    -        ('*Button*activeBackground', tk_style['Button']['activeBackground']),
    -        ('*Button*activeForeground', tk_style['Button']['activeForeground']),
    -        ('*Button*font', tk_style['Button']['font']),
    -        ('*Button*highlightBackground', bg_color),
    -        ('*Button*highlightColor', selected_bg_color),
    -
    -        ('*Label*foreground', tk_style['Label']['foreground']),
    -        ('*Label*background', tk_style['Label']['background']),
    -        ('*Label*activeBackground', tk_style['Label']['activeBackground']),
    -        ('*Label*activeForeground', tk_style['Label']['activeForeground']),
    -        ('*Label*font', tk_style['Label']['font']),
    -        ('*Label*highlightBackground', bg_color),
    -        ('*Label*highlightColor', selected_bg_color),
    -
    -        ('*Message*foreground', tk_style['Message']['foreground']),
    -        ('*Message*background', tk_style['Message']['background']),
    -        ('*Message*activeBackground', tk_style['Message']['activeBackground']),
    -        ('*Message*activeForeground', tk_style['Message']['activeForeground']),
    -        ('*Message*font', tk_style['Message']['font']),
    -        ('*Message*highlightBackground', bg_color),
    -        ('*Message*highlightColor', selected_bg_color),
    -
    -        ('*Checkbutton*foreground', tk_style['Checkbutton']['foreground']),
    -        ('*Checkbutton*background', tk_style['Checkbutton']['background']),
    -        ('*Checkbutton*activeBackground', tk_style['Checkbutton']['activeBackground']),
    -        ('*Checkbutton*activeForeground', tk_style['Checkbutton']['activeForeground']),
    -        ('*Checkbutton*selectColor', tk_style['Checkbutton']['selectColor']),
    -        ('*Checkbutton*font', tk_style['Checkbutton']['font']),
    -        ('*Checkbutton*highlightBackground', bg_color),
    -        ('*Checkbutton*highlightColor', selected_bg_color),
    -
    -        ('*Radiobutton*foreground', tk_style['Radiobutton']['foreground']),
    -        ('*Radiobutton*background', tk_style['Radiobutton']['background']),
    -        ('*Radiobutton*activeBackground', tk_style['Radiobutton']['activeBackground']),
    -        ('*Radiobutton*activeForeground', tk_style['Radiobutton']['activeForeground']),
    -        ('*Radiobutton*selectColor', tk_style['Radiobutton']['selectColor']),
    -        ('*Radiobutton*font', tk_style['Radiobutton']['font']),
    -        ('*Radiobutton*highlightBackground', bg_color),
    -        ('*Radiobutton*highlightColor', selected_bg_color),
    -
    -        ('*Entry*foreground', tk_style['Entry']['foreground']),
    -        ('*Entry*background', tk_style['Entry']['background']),
    -        ('*Entry*selectForeground', tk_style['Entry']['selectForeground']),
    -        ('*Entry*selectBackground', tk_style['Entry']['selectBackground']),
    -        ('*Entry*font', tk_style['Entry']['font']),
    -        ('*Entry*highlightBackground', bg_color),
    -        ('*Entry*highlightColor', selected_bg_color),
    -        ('*Entry*insertBackground', tk_style['Entry']['foreground']),
    -
    -        ('*Text*foreground', tk_style['Text']['foreground']),
    -        ('*Text*background', tk_style['Text']['background']),
    -        ('*Text*selectForeground', tk_style['Text']['selectForeground']),
    -        ('*Text*selectBackground', tk_style['Text']['selectBackground']),
    -        ('*Text*font', tk_style['Text']['font']),
    -        ('*Text*highlightBackground', bg_color),
    -        ('*Text*highlightColor', selected_bg_color),
    -        ('*Text*insertBackground', tk_style['Text']['foreground']),
    -
    -        ('*Spinbox*foreground', tk_style['Spinbox']['foreground']),
    -        ('*Spinbox*background', tk_style['Spinbox']['background']),
    -        ('*Spinbox*selectForeground', tk_style['Spinbox']['selectForeground']),
    -        ('*Spinbox*selectBackground', tk_style['Spinbox']['selectBackground']),
    -        ('*Spinbox*font', tk_style['Spinbox']['font']),
    -        ('*Spinbox*highlightBackground', bg_color),
    -        ('*Spinbox*highlightColor', selected_bg_color),
    -        ('*Spinbox*insertBackground', tk_style['Spinbox']['foreground']),
    -
    -        ('*Menubutton.foreground', tk_style['OptionMenu']['foreground']),
    -        ('*Menubutton.background', tk_style['OptionMenu']['background']),
    -        ('*Menubutton.activeBackground', tk_style['OptionMenu']['activeBackground']),
    -        ('*Menubutton.activeForeground', tk_style['OptionMenu']['activeForeground']),
    -        ('*Menubutton.font', tk_style['OptionMenu']['font']),
    -        ('*Menubutton*highlightBackground', tk_style['OptionMenu']['background']),
    -        ('*Menubutton*highlightColor', tk_style['OptionMenu']['activeForeground']),
    -
    -        ('*Listbox*foreground', tk_style['Listbox']['foreground']),
    -        ('*Listbox*background', tk_style['Listbox']['background']),
    -        ('*Listbox*activeBackground', tk_style['Listbox']['activeBackground']),
    -        ('*Listbox*activeForeground', tk_style['Listbox']['activeForeground']),
    -        ('*Listbox*selectBackground', tk_style['Listbox']['selectBackground']),
    -        ('*Listbox*selectForeground', tk_style['Listbox']['selectForeground']),
    -        ('*Listbox*font', tk_style['Listbox']['font']),
    -        ('*Listbox*highlightBackground', bg_color),
    -        ('*Listbox*highlightColor', selected_bg_color),
    -
    -        ('*Scrollbar*foreground', tk_style['Scrollbar']['foreground']),
    -        ('*Scrollbar*background', tk_style['Scrollbar']['background']),
    -        ('*Scrollbar*activeBackground', tk_style['Scrollbar']['activeBackground']),
    -        ('*Scrollbar*activeForeground', tk_style['Scrollbar']['activeForeground']),
    -        ('*Scrollbar*troughColor', tk_style['Scrollbar']['troughColor']),
    -        ('*Scrollbar*highlightBackground', bg_color),
    -        ('*Scrollbar*highlightColor', selected_bg_color),
    -
    -        ('*Scale*foreground', tk_style['Scale']['foreground']),
    -        ('*Scale*background', tk_style['Scale']['background']),
    -        ('*Scale*activeBackground', tk_style['Scale']['activeBackground']),
    -        ('*Scale*activeForeground', tk_style['Scale']['activeForeground']),
    -        ('*Scale*troughColor', tk_style['Scale']['troughColor']),
    -        ('*Scale*font', tk_style['Scale']['font']),
    -        ('*Scale*highlightBackground', bg_color),
    -        ('*Scale*highlightColor', selected_bg_color),
    -    )
    -    #w.option_add('pattern',value, priority)
    -    for p, v in patterns:
    -        w.option_add(p, v)
    -
    -def apply_gtk_theme_noop(w):
    -    #No gtk installed
    -    pass
    -
    -apply_gtk_theme = apply_gtk_theme_noop
    -if HAS_GTK:
    -    apply_gtk_theme = apply_gtk_theme_real
    +
    # -*- coding: utf-8 -*-
    +
    +#
    +# colour.py
    +#
    +
    +__all__ = ['apply_gtk_theme']
    +
    +import tkFont as tkfont
    +
    +HAS_GTK = False
    +try:
    +    import gtk
    +    HAS_GTK = True
    +except:
    +    pass
    +
    +def _get_color_scheme():
    +    gtkSet = gtk.settings_get_default()
    +    return gtkSet.get_property('gtk-color-scheme')
    +
    +def get_color_scheme_item(colorName):
    +    gtkSch = _get_color_scheme()
    +    findLine = ''
    +    for l in gtkSch.splitlines():
    +        if l.startswith(colorName):
    +            findLine = l
    +            break
    +    c = findLine.replace(colorName+":", "").strip()
    +    c = c.replace("#", "")
    +    rgba = []
    +    if len(c) == 12:
    +        rgba = [c[0:4], c[4:8], c[8:12], ""]
    +    colourFound = '#'
    +    for set in rgba:
    +       colourFound = "".join([colourFound, set[:2].upper()])
    +    if len(colourFound) == 0:
    +        raise error
    +        return None
    +    else:
    +        return colourFound
    +
    +
    +tk_fonts = {}
    +tk_font_families= None
    +
    +def get_tk_font(font_desc):
    +    """Crea una fuente tk"""
    +
    +    global tk_font_families
    +    global tk_fonts
    +
    +    if tk_font_families is None:
    +        tk_font_families = tkfont.families()
    +    font = None
    +    if font_desc in tk_fonts:
    +        font = tk_fonts[font_desc]
    +    else:
    +        family = 'Helvetica'
    +        for x in tk_font_families:
    +            if x in font_desc:
    +                family = x
    +        s = font_desc.split()
    +        size = s[-1]
    +        lower = font_desc.lower()
    +        weight = 'normal'
    +        slant = 'roman'
    +        if 'bold' in lower:
    +            weight = 'bold'
    +        if 'italic' in lower:
    +            slant='italic'
    +        #print '%s, %s, %s, %s' % (family, weight, slant, size)
    +        f = tkfont.Font(family=family, size=size, weight=weight, slant=slant )
    +        tk_fonts[font_desc]= font = f
    +    return font
    +
    +
    +#gtk_states = [gtk.STATE_NORMAL, gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE, gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE]
    +
    +def get_tk_styles():
    +    """Toma los estilos de Gtk y los "traduce" a estilos tk."""
    +    tk_styles = {}
    +
    +    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    +        '*<GtkLabel>*', '<GtkLabel>', gtk.Label)
    +    c = {
    +        'foreground': str(style.text[gtk.STATE_NORMAL]),
    +        'background': str(style.bg[gtk.STATE_NORMAL]),
    +        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    +        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    +        'font': get_tk_font(str(style.font_desc)),
    +    }
    +    tk_styles['Label'] = label = c
    +    tk_styles['Message'] = c
    +
    +    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    +        '*<GtkEntry>*', 'GtkEntry', gtk.Entry)
    +    c = {
    +        'foreground': str(style.text[gtk.STATE_NORMAL]),
    +        'background': get_color_scheme_item('base_color'),
    +        'selectForeground': str(style.text[gtk.STATE_SELECTED]),
    +        'selectBackground': str(style.bg[gtk.STATE_SELECTED]),
    +        'activeForeground': str(style.bg[gtk.STATE_NORMAL]),
    +        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    +        'font': get_tk_font(str(style.font_desc)),
    +    }
    +    tk_styles['Entry'] = c
    +    tk_styles['Text'] = c
    +    tk_styles['Spinbox'] = c
    +
    +    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    +        '*<GtkMenuBar>*', 'GtkMenuBar', gtk.MenuBar)
    +    c = {
    +        'foreground': str(style.text[gtk.STATE_NORMAL]),
    +        'background': str(style.bg[gtk.STATE_NORMAL]),
    +        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    +        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    +        'font': get_tk_font(str(style.font_desc)),
    +    }
    +    tk_styles['Menu'] = c
    +
    +    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    +        '*<GtkButton>*', 'GtkButton', gtk.Button)
    +    c = {
    +        'foreground': str(style.text[gtk.STATE_NORMAL]),
    +        'background': str(style.bg[gtk.STATE_NORMAL]),
    +        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    +        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    +        'font': get_tk_font(str(style.font_desc)),
    +    }
    +    tk_styles['Button'] = c
    +    tk_styles['OptionMenu'] = c
    +
    +    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    +        '*<GtkCheck>*', 'GtkCheck', gtk.CheckButton)
    +    c = {
    +        'foreground': label['foreground'],
    +        'background': label['background'],
    +        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    +        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    +        'selectColor': str(style.bg[gtk.STATE_SELECTED]),
    +        'font': get_tk_font(str(style.font_desc)),
    +    }
    +    tk_styles['Checkbutton'] = c
    +
    +    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    +        '*<GtkRadio>*', 'GtkRadio', gtk.RadioButton)
    +    c = {
    +        'foreground': label['foreground'],
    +        'background': label['background'],
    +        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    +        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    +        'selectColor': str(style.bg[gtk.STATE_SELECTED]),
    +        'font': get_tk_font(str(style.font_desc)),
    +    }
    +    tk_styles['Radiobutton'] = c
    +
    +    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    +        '*<GtkList>*', 'GtkList', gtk.List)
    +    c = {
    +        'foreground': str(style.text[gtk.STATE_NORMAL]),
    +        'background': str(style.bg[gtk.STATE_NORMAL]),
    +        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    +        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    +        'selectForeground': str(style.text[gtk.STATE_SELECTED]),
    +        'selectBackground': str(style.bg[gtk.STATE_SELECTED]),
    +        'font': get_tk_font(str(style.font_desc)),
    +    }
    +    tk_styles['Listbox'] = c
    +
    +    style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
    +        '*<GtkScrollbar>*', 'GtkScrollbar', gtk.Scrollbar)
    +    c = {
    +        'foreground': str(style.text[gtk.STATE_NORMAL]),
    +        'background': str(style.bg[gtk.STATE_NORMAL]),
    +        'activeForeground': str(style.text[gtk.STATE_SELECTED]),
    +        'activeBackground': str(style.bg[gtk.STATE_SELECTED]),
    +        'troughColor': str(style.bg[gtk.STATE_ACTIVE]),
    +        'font': get_tk_font(str(style.font_desc)),
    +    }
    +    tk_styles['Scrollbar'] = c
    +    tk_styles['Scale'] = c
    +
    +    return tk_styles
    +
    +
    +def apply_gtk_theme_real(w):
    +    tk_style = get_tk_styles()
    +    bg_color = get_color_scheme_item('bg_color')
    +    selected_bg_color = get_color_scheme_item('selected_bg_color')
    +    patterns = (
    +        ('*Frame*background', bg_color),
    +
    +        ('*Menu*foreground', tk_style['Menu']['foreground']),
    +        ('*Menu*background', tk_style['Menu']['background']),
    +        ('*Menu*activeBackground', tk_style['Menu']['activeBackground']),
    +        ('*Menu*activeForeground', tk_style['Menu']['activeForeground']),
    +        ('*Menu*font', tk_style['Menu']['font']),
    +        ('*Menu*highlightBackground', bg_color),
    +        ('*Menu*highlightColor', selected_bg_color),
    +
    +        ('*Button*foreground', tk_style['Button']['foreground']),
    +        ('*Button*background', tk_style['Button']['background']),
    +        ('*Button*activeBackground', tk_style['Button']['activeBackground']),
    +        ('*Button*activeForeground', tk_style['Button']['activeForeground']),
    +        ('*Button*font', tk_style['Button']['font']),
    +        ('*Button*highlightBackground', bg_color),
    +        ('*Button*highlightColor', selected_bg_color),
    +
    +        ('*Label*foreground', tk_style['Label']['foreground']),
    +        ('*Label*background', tk_style['Label']['background']),
    +        ('*Label*activeBackground', tk_style['Label']['activeBackground']),
    +        ('*Label*activeForeground', tk_style['Label']['activeForeground']),
    +        ('*Label*font', tk_style['Label']['font']),
    +        ('*Label*highlightBackground', bg_color),
    +        ('*Label*highlightColor', selected_bg_color),
    +
    +        ('*Message*foreground', tk_style['Message']['foreground']),
    +        ('*Message*background', tk_style['Message']['background']),
    +        ('*Message*activeBackground', tk_style['Message']['activeBackground']),
    +        ('*Message*activeForeground', tk_style['Message']['activeForeground']),
    +        ('*Message*font', tk_style['Message']['font']),
    +        ('*Message*highlightBackground', bg_color),
    +        ('*Message*highlightColor', selected_bg_color),
    +
    +        ('*Checkbutton*foreground', tk_style['Checkbutton']['foreground']),
    +        ('*Checkbutton*background', tk_style['Checkbutton']['background']),
    +        ('*Checkbutton*activeBackground', tk_style['Checkbutton']['activeBackground']),
    +        ('*Checkbutton*activeForeground', tk_style['Checkbutton']['activeForeground']),
    +        ('*Checkbutton*selectColor', tk_style['Checkbutton']['selectColor']),
    +        ('*Checkbutton*font', tk_style['Checkbutton']['font']),
    +        ('*Checkbutton*highlightBackground', bg_color),
    +        ('*Checkbutton*highlightColor', selected_bg_color),
    +
    +        ('*Radiobutton*foreground', tk_style['Radiobutton']['foreground']),
    +        ('*Radiobutton*background', tk_style['Radiobutton']['background']),
    +        ('*Radiobutton*activeBackground', tk_style['Radiobutton']['activeBackground']),
    +        ('*Radiobutton*activeForeground', tk_style['Radiobutton']['activeForeground']),
    +        ('*Radiobutton*selectColor', tk_style['Radiobutton']['selectColor']),
    +        ('*Radiobutton*font', tk_style['Radiobutton']['font']),
    +        ('*Radiobutton*highlightBackground', bg_color),
    +        ('*Radiobutton*highlightColor', selected_bg_color),
    +
    +        ('*Entry*foreground', tk_style['Entry']['foreground']),
    +        ('*Entry*background', tk_style['Entry']['background']),
    +        ('*Entry*selectForeground', tk_style['Entry']['selectForeground']),
    +        ('*Entry*selectBackground', tk_style['Entry']['selectBackground']),
    +        ('*Entry*font', tk_style['Entry']['font']),
    +        ('*Entry*highlightBackground', bg_color),
    +        ('*Entry*highlightColor', selected_bg_color),
    +        ('*Entry*insertBackground', tk_style['Entry']['foreground']),
    +
    +        ('*Text*foreground', tk_style['Text']['foreground']),
    +        ('*Text*background', tk_style['Text']['background']),
    +        ('*Text*selectForeground', tk_style['Text']['selectForeground']),
    +        ('*Text*selectBackground', tk_style['Text']['selectBackground']),
    +        ('*Text*font', tk_style['Text']['font']),
    +        ('*Text*highlightBackground', bg_color),
    +        ('*Text*highlightColor', selected_bg_color),
    +        ('*Text*insertBackground', tk_style['Text']['foreground']),
    +
    +        ('*Spinbox*foreground', tk_style['Spinbox']['foreground']),
    +        ('*Spinbox*background', tk_style['Spinbox']['background']),
    +        ('*Spinbox*selectForeground', tk_style['Spinbox']['selectForeground']),
    +        ('*Spinbox*selectBackground', tk_style['Spinbox']['selectBackground']),
    +        ('*Spinbox*font', tk_style['Spinbox']['font']),
    +        ('*Spinbox*highlightBackground', bg_color),
    +        ('*Spinbox*highlightColor', selected_bg_color),
    +        ('*Spinbox*insertBackground', tk_style['Spinbox']['foreground']),
    +
    +        ('*Menubutton.foreground', tk_style['OptionMenu']['foreground']),
    +        ('*Menubutton.background', tk_style['OptionMenu']['background']),
    +        ('*Menubutton.activeBackground', tk_style['OptionMenu']['activeBackground']),
    +        ('*Menubutton.activeForeground', tk_style['OptionMenu']['activeForeground']),
    +        ('*Menubutton.font', tk_style['OptionMenu']['font']),
    +        ('*Menubutton*highlightBackground', tk_style['OptionMenu']['background']),
    +        ('*Menubutton*highlightColor', tk_style['OptionMenu']['activeForeground']),
    +
    +        ('*Listbox*foreground', tk_style['Listbox']['foreground']),
    +        ('*Listbox*background', tk_style['Listbox']['background']),
    +        ('*Listbox*activeBackground', tk_style['Listbox']['activeBackground']),
    +        ('*Listbox*activeForeground', tk_style['Listbox']['activeForeground']),
    +        ('*Listbox*selectBackground', tk_style['Listbox']['selectBackground']),
    +        ('*Listbox*selectForeground', tk_style['Listbox']['selectForeground']),
    +        ('*Listbox*font', tk_style['Listbox']['font']),
    +        ('*Listbox*highlightBackground', bg_color),
    +        ('*Listbox*highlightColor', selected_bg_color),
    +
    +        ('*Scrollbar*foreground', tk_style['Scrollbar']['foreground']),
    +        ('*Scrollbar*background', tk_style['Scrollbar']['background']),
    +        ('*Scrollbar*activeBackground', tk_style['Scrollbar']['activeBackground']),
    +        ('*Scrollbar*activeForeground', tk_style['Scrollbar']['activeForeground']),
    +        ('*Scrollbar*troughColor', tk_style['Scrollbar']['troughColor']),
    +        ('*Scrollbar*highlightBackground', bg_color),
    +        ('*Scrollbar*highlightColor', selected_bg_color),
    +
    +        ('*Scale*foreground', tk_style['Scale']['foreground']),
    +        ('*Scale*background', tk_style['Scale']['background']),
    +        ('*Scale*activeBackground', tk_style['Scale']['activeBackground']),
    +        ('*Scale*activeForeground', tk_style['Scale']['activeForeground']),
    +        ('*Scale*troughColor', tk_style['Scale']['troughColor']),
    +        ('*Scale*font', tk_style['Scale']['font']),
    +        ('*Scale*highlightBackground', bg_color),
    +        ('*Scale*highlightColor', selected_bg_color),
    +    )
    +    #w.option_add('pattern',value, priority)
    +    for p, v in patterns:
    +        w.option_add(p, v)
    +
    +def apply_gtk_theme_noop(w):
    +    #No gtk installed
    +    pass
    +
    +apply_gtk_theme = apply_gtk_theme_noop
    +if HAS_GTK:
    +    apply_gtk_theme = apply_gtk_theme_real
     

    Ejemplo:

    Descripcion: Crea 2 ventanas pequeñas iguales, una tratara de imitar el tema de GTK, la otra se mostrara como es por defecto.

    -
    #!/usr/bin/env python2
    -#-*- coding:utf-8 -*-
    -
    -#
    -# test.py
    -#
    -
    -import Tkinter as tk
    -import colour
    -
    -class GtkOnTkApp(tk.Frame):
    -    '''Gtk on tk test"'''
    -
    -    def __entry_scrollHandler(self, *L):
    -        op, howMany = L[0], L[1]
    -        if op == "scroll":
    -            units = L[2]
    -            self.entry.xview_scroll ( howMany, units )
    -        elif op == "moveto":
    -            self.entry.xview_moveto ( howMany )
    -
    -
    -    def __init__(self, master, title):
    -        tk.Frame.__init__(self, master)
    -        root = self.winfo_toplevel()
    -
    -        o = tk.Label(self, text="Label: " + title)
    -        o.pack(side='top', pady=2)
    -
    -        o = tk.Button(self, text="Button")
    -        o.pack(side='top', pady=2)
    -
    -        self.entry = o = tk.Entry(self)
    -        o.insert('end', 'Entry + Scrollbar ' * 10)
    -        o.pack(side='top', pady=2)
    -
    -        o = tk.Scrollbar(self,orient='horizontal', command=self.__entry_scrollHandler)
    -        o.pack(side='top', fill='x', pady=2)
    -        self.entry.configure(xscrollcommand=o.set)
    -
    -        o = tk.Spinbox(self, from_=0, to=50)
    -        o.pack(side='top', pady=2)
    -
    -        opciones = ('OptionMenu', 'Opcion2', 'Opcion3')
    -        self.ovar = tk.StringVar()
    -        self.ovar.set(opciones[0])
    -        o = tk.OptionMenu(self, self.ovar, *opciones)
    -        o.pack(side='top', pady=2)
    -
    -        self.items = tk.StringVar()
    -        self.items.set('Listbox Item2 Item3')
    -        o = tk.Listbox(self, listvariable=self.items, height=3)
    -        o.pack(side='top', fill='x', pady=2)
    -
    -        o = tk.Checkbutton(self,text='Checkbutton')
    -        o.pack(side='top', pady=2)
    -
    -        self.rbar = tk.IntVar()
    -        self.rbar.set(0)
    -        o = tk.Radiobutton(self,text='Radiobutton1', value=0, variable=self.rbar)
    -        o.pack(side='top', pady=2)
    -        o = tk.Radiobutton(self,text='Radiobutton2', value=1, variable=self.rbar)
    -        o.pack(side='top', pady=2)
    -
    -        o = tk.Scale(self,label='Scale', orient='horizontal')
    -        o.pack(side='top', fill='x', pady=2)
    -
    -        o = tk.Message(self, text='Message widget')
    -        o.pack(side='top', fill='x', pady=2)
    -
    -        o = tk.Text(self, height=4)
    -        o.insert('0.0', 'Text widget ' * 20)
    -        o.pack(side='top', pady=2)
    -
    -        self.pack(expand=True, fill='both')
    -
    -        # Menubar
    -        menubar = tk.Menu(root)
    -        filemenu = tk.Menu(menubar, tearoff=0)
    -        filemenu.add_command(label="Nuevo", state='disabled')
    -        filemenu.add_command(label="Menuitem 2")
    -        filemenu.add_command(label="Menuitem 3")
    -        filemenu.add_separator()
    -        filemenu.add_command(label="Cerrar ✗", command= lambda: root.destroy())
    -        menubar.add_cascade(label="Archivo", menu=filemenu)
    -        root.config(menu=menubar)
    -        root.title(title)
    -
    -
    -if __name__ == '__main__':
    -    root = tk.Tk()
    -    # Creamos una ventana sin estilos
    -    app1 = GtkOnTkApp(tk.Toplevel(), 'Ventana sin tema Gtk')
    -
    -    # Definimos los estilos gtk. Despues de la llamada a apply_gtk_theme
    -    # los widgets que se crean posen "estilo" gtk:
    -    colour.apply_gtk_theme(root)
    -    #Creamos ventana con estilos
    -    app2 = GtkOnTkApp(root, 'Ventana con tema Gtk')
    -    root.mainloop()
    +
    #!/usr/bin/env python2
    +#-*- coding:utf-8 -*-
    +
    +#
    +# test.py
    +#
    +
    +import Tkinter as tk
    +import colour
    +
    +class GtkOnTkApp(tk.Frame):
    +    '''Gtk on tk test"'''
    +
    +    def __entry_scrollHandler(self, *L):
    +        op, howMany = L[0], L[1]
    +        if op == "scroll":
    +            units = L[2]
    +            self.entry.xview_scroll ( howMany, units )
    +        elif op == "moveto":
    +            self.entry.xview_moveto ( howMany )
    +
    +
    +    def __init__(self, master, title):
    +        tk.Frame.__init__(self, master)
    +        root = self.winfo_toplevel()
    +
    +        o = tk.Label(self, text="Label: " + title)
    +        o.pack(side='top', pady=2)
    +
    +        o = tk.Button(self, text="Button")
    +        o.pack(side='top', pady=2)
    +
    +        self.entry = o = tk.Entry(self)
    +        o.insert('end', 'Entry + Scrollbar ' * 10)
    +        o.pack(side='top', pady=2)
    +
    +        o = tk.Scrollbar(self,orient='horizontal', command=self.__entry_scrollHandler)
    +        o.pack(side='top', fill='x', pady=2)
    +        self.entry.configure(xscrollcommand=o.set)
    +
    +        o = tk.Spinbox(self, from_=0, to=50)
    +        o.pack(side='top', pady=2)
    +
    +        opciones = ('OptionMenu', 'Opcion2', 'Opcion3')
    +        self.ovar = tk.StringVar()
    +        self.ovar.set(opciones[0])
    +        o = tk.OptionMenu(self, self.ovar, *opciones)
    +        o.pack(side='top', pady=2)
    +
    +        self.items = tk.StringVar()
    +        self.items.set('Listbox Item2 Item3')
    +        o = tk.Listbox(self, listvariable=self.items, height=3)
    +        o.pack(side='top', fill='x', pady=2)
    +
    +        o = tk.Checkbutton(self,text='Checkbutton')
    +        o.pack(side='top', pady=2)
    +
    +        self.rbar = tk.IntVar()
    +        self.rbar.set(0)
    +        o = tk.Radiobutton(self,text='Radiobutton1', value=0, variable=self.rbar)
    +        o.pack(side='top', pady=2)
    +        o = tk.Radiobutton(self,text='Radiobutton2', value=1, variable=self.rbar)
    +        o.pack(side='top', pady=2)
    +
    +        o = tk.Scale(self,label='Scale', orient='horizontal')
    +        o.pack(side='top', fill='x', pady=2)
    +
    +        o = tk.Message(self, text='Message widget')
    +        o.pack(side='top', fill='x', pady=2)
    +
    +        o = tk.Text(self, height=4)
    +        o.insert('0.0', 'Text widget ' * 20)
    +        o.pack(side='top', pady=2)
    +
    +        self.pack(expand=True, fill='both')
    +
    +        # Menubar
    +        menubar = tk.Menu(root)
    +        filemenu = tk.Menu(menubar, tearoff=0)
    +        filemenu.add_command(label="Nuevo", state='disabled')
    +        filemenu.add_command(label="Menuitem 2")
    +        filemenu.add_command(label="Menuitem 3")
    +        filemenu.add_separator()
    +        filemenu.add_command(label="Cerrar ✗", command= lambda: root.destroy())
    +        menubar.add_cascade(label="Archivo", menu=filemenu)
    +        root.config(menu=menubar)
    +        root.title(title)
    +
    +
    +if __name__ == '__main__':
    +    root = tk.Tk()
    +    # Creamos una ventana sin estilos
    +    app1 = GtkOnTkApp(tk.Toplevel(), 'Ventana sin tema Gtk')
    +
    +    # Definimos los estilos gtk. Despues de la llamada a apply_gtk_theme
    +    # los widgets que se crean posen "estilo" gtk:
    +    colour.apply_gtk_theme(root)
    +    #Creamos ventana con estilos
    +    app2 = GtkOnTkApp(root, 'Ventana con tema Gtk')
    +    root.mainloop()
     

    Capturas:

    /images/GTKonTK/gtkontk01.png/images/GTKonTK/gtkontk02.png diff --git a/recetario/gui/gtk/autocomplete/index.html b/recetario/gui/gtk/autocomplete/index.html index 65a7b4917..ac0fbeace 100644 --- a/recetario/gui/gtk/autocomplete/index.html +++ b/recetario/gui/gtk/autocomplete/index.html @@ -32,7 +32,7 @@ gtk.Entry.__init__(self) self"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - +
    @@ -91,33 +91,33 @@

    Gtk Auto Complete

    Ejemplo de campo de texto con auto completación.

    -
    import gtk
    -
    -class Complete(gtk.Entry):
    -    '''a class to autocomplete'''
    -
    -    def __init__(self, *words):
    -        gtk.Entry.__init__(self)
    -        self.completion = gtk.EntryCompletion()
    -        self.set_completion(self.completion)
    -        self.model = gtk.ListStore(str)
    -        self.completion.set_model(self.model)
    -        self.completion.set_text_column(0)
    -
    -        for word in words:
    -            self.remember(word)
    -
    -    def remember(self, value):
    -        '''add a value to the list of strings to suggest'''
    -        self.model.append([value])
    -
    -if __name__ == '__main__':
    -    window = gtk.Window()
    -    complete = Complete("python", "pyar", "span", "eggs")
    -    window.add(complete)
    -    window.connect('delete-event', gtk.main_quit)
    -    window.show_all()
    -    gtk.main()
    +
    import gtk
    +
    +class Complete(gtk.Entry):
    +    '''a class to autocomplete'''
    +
    +    def __init__(self, *words):
    +        gtk.Entry.__init__(self)
    +        self.completion = gtk.EntryCompletion()
    +        self.set_completion(self.completion)
    +        self.model = gtk.ListStore(str)
    +        self.completion.set_model(self.model)
    +        self.completion.set_text_column(0)
    +
    +        for word in words:
    +            self.remember(word)
    +
    +    def remember(self, value):
    +        '''add a value to the list of strings to suggest'''
    +        self.model.append([value])
    +
    +if __name__ == '__main__':
    +    window = gtk.Window()
    +    complete = Complete("python", "pyar", "span", "eggs")
    +    window.add(complete)
    +    window.connect('delete-event', gtk.main_quit)
    +    window.show_all()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/browserconwebinspector/index.html b/recetario/gui/gtk/browserconwebinspector/index.html index 5a7cb5435..189cd20af 100644 --- a/recetario/gui/gtk/browserconwebinspector/index.html +++ b/recetario/gui/gtk/browserconwebinspector/index.html @@ -26,7 +26,7 @@ En este caso vemos cómo agregar el web inspector para inspeccionar y debuggear la página que estamos viendo. El resultado '> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -89,78 +89,78 @@

    Gtk Browser Con Web Inspector

    El resultado al principio es algo así:

    /images/Recetario/Gui/Gtk/BrowserConWebInspector/brser1.png

    Luego de hacer click derecho en la página y hacer click en "Inspect Element" tenemos algo así:

    /images/Recetario/Gui/Gtk/BrowserConWebInspector/brser2.png

    El código:

    -
    import sys
    -import gtk
    -import webkit
    -
    -class Browser(gtk.Window):
    -    def __init__(self, url=''):
    -        gtk.Window.__init__(self)
    -
    -        self.url = url
    -        self.view = webkit.WebView()
    -
    -        self.set_title('Browser')
    -        self.set_default_size(640, 480)
    -
    -        scroll = gtk.ScrolledWindow()
    -        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    -        scroll.set_shadow_type(gtk.SHADOW_IN)
    -
    -        scroll.add(self.view)
    -
    -        vbox = gtk.VBox()
    -
    -        entry = gtk.Entry()
    -        entry.connect('activate', self._on_url_changed)
    -
    -        if self.url:
    -            entry.set_text(self.url)
    -            self.open(self.url)
    -
    -        vbox.pack_start(entry, False)
    -        vbox.pack_start(scroll, True, True)
    -
    -        panels = gtk.VPaned()
    -        panels.add1(vbox)
    -        panels.show_all()
    -
    -        settings = self.view.get_settings()
    -        settings.set_property("enable-developer-extras", True)
    -
    -        def activate_inspector(self, *args):
    -            view = webkit.WebView()
    -
    -            panels.add2(view)
    -            panels.set_position(panels.get_allocation().height / 2)
    -            view.show()
    -
    -            return view
    -
    -        inspector = self.view.get_web_inspector()
    -        inspector.connect("inspect-web-view", activate_inspector)
    -
    -        self.add(panels)
    -
    -        self.connect('delete-event', lambda *args: sys.exit(0))
    -
    -    def open(self, url):
    -        if not url.startswith('http://') and not url.startswith('https://'):
    -            self.url = 'http://' + url
    -        else:
    -            self.url = url
    -
    -        self.view.open(self.url)
    -
    -    def _on_url_changed(self, entry):
    -        '''called when the url changes'''
    -        url = entry.get_text()
    -        self.open(url)
    -
    -if __name__ == '__main__':
    -    browser = Browser('www.google.com/search?q=python%20argentina')
    -    browser.show()
    -    gtk.main()
    +
    import sys
    +import gtk
    +import webkit
    +
    +class Browser(gtk.Window):
    +    def __init__(self, url=''):
    +        gtk.Window.__init__(self)
    +
    +        self.url = url
    +        self.view = webkit.WebView()
    +
    +        self.set_title('Browser')
    +        self.set_default_size(640, 480)
    +
    +        scroll = gtk.ScrolledWindow()
    +        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    +        scroll.set_shadow_type(gtk.SHADOW_IN)
    +
    +        scroll.add(self.view)
    +
    +        vbox = gtk.VBox()
    +
    +        entry = gtk.Entry()
    +        entry.connect('activate', self._on_url_changed)
    +
    +        if self.url:
    +            entry.set_text(self.url)
    +            self.open(self.url)
    +
    +        vbox.pack_start(entry, False)
    +        vbox.pack_start(scroll, True, True)
    +
    +        panels = gtk.VPaned()
    +        panels.add1(vbox)
    +        panels.show_all()
    +
    +        settings = self.view.get_settings()
    +        settings.set_property("enable-developer-extras", True)
    +
    +        def activate_inspector(self, *args):
    +            view = webkit.WebView()
    +
    +            panels.add2(view)
    +            panels.set_position(panels.get_allocation().height / 2)
    +            view.show()
    +
    +            return view
    +
    +        inspector = self.view.get_web_inspector()
    +        inspector.connect("inspect-web-view", activate_inspector)
    +
    +        self.add(panels)
    +
    +        self.connect('delete-event', lambda *args: sys.exit(0))
    +
    +    def open(self, url):
    +        if not url.startswith('http://') and not url.startswith('https://'):
    +            self.url = 'http://' + url
    +        else:
    +            self.url = url
    +
    +        self.view.open(self.url)
    +
    +    def _on_url_changed(self, entry):
    +        '''called when the url changes'''
    +        url = entry.get_text()
    +        self.open(url)
    +
    +if __name__ == '__main__':
    +    browser = Browser('www.google.com/search?q=python%20argentina')
    +    browser.show()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/button/index.html b/recetario/gui/gtk/button/index.html index cd86b3762..8dfecb35d 100644 --- a/recetario/gui/gtk/button/index.html +++ b/recetario/gui/gtk/button/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/recetario/gui/gtk/buttonbox/index.html b/recetario/gui/gtk/buttonbox/index.html index c0fa89782..85e7e817f 100644 --- a/recetario/gui/gtk/buttonbox/index.html +++ b/recetario/gui/gtk/buttonbox/index.html @@ -28,7 +28,7 @@ window = gtk.Window"> - +Ir al contenido principal @@ -62,12 +62,12 @@ - + @@ -87,57 +87,57 @@

    Buttonbox

    Este ejemplo muestra cómo usar un contenedor de botones para agregar botones, hacer que mantengan su forma óptima y se distribuyan por la pantalla de manera homogénea.

    -/images/Recetario/Gui/Gtk/ButtonBox/buttonbox-demo.png
    import gtk
    -
    -window = gtk.Window()
    -window.set_default_size(640, 480)
    -window.set_title("button box demo")
    -
    -vbox = gtk.VBox()
    -
    -hbox1 = gtk.HButtonBox()
    -hbox1.pack_start(gtk.Button(stock=gtk.STOCK_OK))
    -
    -def build_bbox():
    -        """build a hbox fill it with example buttons and return it"""
    -        hbox = gtk.HButtonBox()
    -
    -        hbox.pack_start(gtk.Button(stock=gtk.STOCK_YES))
    -        hbox.pack_start(gtk.Button(stock=gtk.STOCK_NO))
    -
    -        return hbox
    -
    -hbox2 = build_bbox()
    -hbox2.set_layout(gtk.BUTTONBOX_SPREAD)
    -
    -hbox3 = build_bbox()
    -hbox3.set_layout(gtk.BUTTONBOX_EDGE)
    -
    -hbox4 = build_bbox()
    -hbox4.set_layout(gtk.BUTTONBOX_START)
    -
    -hbox5 = build_bbox()
    -hbox5.set_layout(gtk.BUTTONBOX_END)
    -
    -hbox6 = build_bbox()
    -hbox6.set_layout(gtk.BUTTONBOX_END)
    -help_button = gtk.Button(stock=gtk.STOCK_HELP)
    -hbox6.pack_start(help_button)
    -hbox6.set_child_secondary(help_button, True)
    -
    -vbox.pack_start(hbox1)
    -vbox.pack_start(hbox2)
    -vbox.pack_start(hbox3)
    -vbox.pack_start(hbox4)
    -vbox.pack_start(hbox5)
    -vbox.pack_start(hbox6)
    -
    -window.add(vbox)
    -window.show_all()
    -
    -window.connect('destroy', gtk.main_quit)
    -
    -gtk.main()
    +/images/Recetario/Gui/Gtk/ButtonBox/buttonbox-demo.png
    import gtk
    +
    +window = gtk.Window()
    +window.set_default_size(640, 480)
    +window.set_title("button box demo")
    +
    +vbox = gtk.VBox()
    +
    +hbox1 = gtk.HButtonBox()
    +hbox1.pack_start(gtk.Button(stock=gtk.STOCK_OK))
    +
    +def build_bbox():
    +        """build a hbox fill it with example buttons and return it"""
    +        hbox = gtk.HButtonBox()
    +
    +        hbox.pack_start(gtk.Button(stock=gtk.STOCK_YES))
    +        hbox.pack_start(gtk.Button(stock=gtk.STOCK_NO))
    +
    +        return hbox
    +
    +hbox2 = build_bbox()
    +hbox2.set_layout(gtk.BUTTONBOX_SPREAD)
    +
    +hbox3 = build_bbox()
    +hbox3.set_layout(gtk.BUTTONBOX_EDGE)
    +
    +hbox4 = build_bbox()
    +hbox4.set_layout(gtk.BUTTONBOX_START)
    +
    +hbox5 = build_bbox()
    +hbox5.set_layout(gtk.BUTTONBOX_END)
    +
    +hbox6 = build_bbox()
    +hbox6.set_layout(gtk.BUTTONBOX_END)
    +help_button = gtk.Button(stock=gtk.STOCK_HELP)
    +hbox6.pack_start(help_button)
    +hbox6.set_child_secondary(help_button, True)
    +
    +vbox.pack_start(hbox1)
    +vbox.pack_start(hbox2)
    +vbox.pack_start(hbox3)
    +vbox.pack_start(hbox4)
    +vbox.pack_start(hbox5)
    +vbox.pack_start(hbox6)
    +
    +window.add(vbox)
    +window.show_all()
    +
    +window.connect('destroy', gtk.main_quit)
    +
    +gtk.main()
     

    Más Información:

    @@ -91,55 +91,55 @@

    Gtkconfirmclose

    Ejemplo de cómo solicitar una confirmación de cierre en una ventana.

    -
    import sys
    -import gtk
    -
    -class VentanaPrincipal(gtk.Window):
    -    '''la ventana principal'''
    -
    -    def __init__(self):
    -        '''constructor'''
    -        gtk.Window.__init__(self)
    -        self.set_default_size(300, 200)
    -        self.set_title('Ejemplo')
    -
    -        label = gtk.Label('cerrame')
    -        label.show()
    -
    -        self.add(label)
    -        self.connect('delete-event', self._on_close)
    -
    -    def _on_close(self, widget, event):
    -        '''metodo llamado cuando aprietan el boton cerrar'''
    -        if not self.confirmar_cierre():
    -            return True
    -        else:
    -            sys.exit(0)
    -
    -    def confirmar_cierre(self):
    -        '''muestra un dialogo que pregunta si esta seguro que
    -        quiere cerrar, devuelve True si selecciona si'''
    -        dialogo = gtk.MessageDialog(self, type=gtk.MESSAGE_QUESTION,
    -            buttons=gtk.BUTTONS_YES_NO,
    -            message_format="Esta seguro que desea salir?")
    -
    -        response = dialogo.run()
    -        dialogo.hide()
    -
    -        if response == gtk.RESPONSE_YES:
    -            return True
    -
    -        return False
    -
    -
    -def test():
    -    '''prueba la implementacion'''
    -    ventana = VentanaPrincipal()
    -    ventana.show()
    -    gtk.main()
    -
    -if __name__ == '__main__':
    -    test()
    +
    import sys
    +import gtk
    +
    +class VentanaPrincipal(gtk.Window):
    +    '''la ventana principal'''
    +
    +    def __init__(self):
    +        '''constructor'''
    +        gtk.Window.__init__(self)
    +        self.set_default_size(300, 200)
    +        self.set_title('Ejemplo')
    +
    +        label = gtk.Label('cerrame')
    +        label.show()
    +
    +        self.add(label)
    +        self.connect('delete-event', self._on_close)
    +
    +    def _on_close(self, widget, event):
    +        '''metodo llamado cuando aprietan el boton cerrar'''
    +        if not self.confirmar_cierre():
    +            return True
    +        else:
    +            sys.exit(0)
    +
    +    def confirmar_cierre(self):
    +        '''muestra un dialogo que pregunta si esta seguro que
    +        quiere cerrar, devuelve True si selecciona si'''
    +        dialogo = gtk.MessageDialog(self, type=gtk.MESSAGE_QUESTION,
    +            buttons=gtk.BUTTONS_YES_NO,
    +            message_format="Esta seguro que desea salir?")
    +
    +        response = dialogo.run()
    +        dialogo.hide()
    +
    +        if response == gtk.RESPONSE_YES:
    +            return True
    +
    +        return False
    +
    +
    +def test():
    +    '''prueba la implementacion'''
    +    ventana = VentanaPrincipal()
    +    ventana.show()
    +    gtk.main()
    +
    +if __name__ == '__main__':
    +    test()
     
    diff --git a/recetario/gui/gtk/dialog/index.html b/recetario/gui/gtk/dialog/index.html index 245799dc7..ce17ec823 100644 --- a/recetario/gui/gtk/dialog/index.html +++ b/recetario/gui/gtk/dialog/index.html @@ -29,7 +29,7 @@ # por defecto crea un mensaje de informacion sin botones info = gtk.MessageDialog(message_format="i'> - +Ir al contenido principal @@ -63,12 +63,12 @@ - + @@ -88,52 +88,52 @@

    Gtkdialog

    Ejemplo para crear diálogos modales de distintos tipos con distintos botones.

    -
    import gtk
    -import sys
    -
    -# por defecto crea un mensaje de informacion sin botones
    -info = gtk.MessageDialog(message_format="informacion!")
    -# tipo advertencia con un boton de ok
    -warning = gtk.MessageDialog(type=gtk.MESSAGE_WARNING,
    -    buttons=gtk.BUTTONS_OK_CANCEL, message_format="advertencia..")
    -# pregunta con botones si no
    -question = gtk.MessageDialog(type=gtk.MESSAGE_QUESTION,
    -    buttons=gtk.BUTTONS_YES_NO, message_format="pregunta?")
    -# error con boton ok
    -error = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
    -    buttons=gtk.BUTTONS_OK, message_format="error!?!")
    -
    -# run bloquea hasta que se produzca un evento y devuelve el valor del evento
    -if info.run() == gtk.RESPONSE_DELETE_EVENT:
    -    print "si, es la unica senial que puede emitir, ya que no tiene botones"
    -# hay que esconder el dialogo
    -info.hide()
    -
    -# almacenamos el valor de retorno en una variable para controlar varios valores
    -response = warning.run()
    -warning.hide()
    -
    -if response == gtk.RESPONSE_OK:
    -    print "advertencia respondio aceptar"
    -elif response == gtk.RESPONSE_CANCEL:
    -    print "advertencia respondio cancel"
    -
    -response = question.run()
    -
    -if response == gtk.RESPONSE_YES:
    -    print "respondio si!"
    -elif response == gtk.RESPONSE_NO:
    -    print "respondio no :("
    -
    -question.hide()
    -
    -if error.run() == gtk.RESPONSE_OK:
    -    print "error OK"
    -
    -error.hide()
    -sys.exit(0)
    -
    -gtk.main()
    +
    import gtk
    +import sys
    +
    +# por defecto crea un mensaje de informacion sin botones
    +info = gtk.MessageDialog(message_format="informacion!")
    +# tipo advertencia con un boton de ok
    +warning = gtk.MessageDialog(type=gtk.MESSAGE_WARNING,
    +    buttons=gtk.BUTTONS_OK_CANCEL, message_format="advertencia..")
    +# pregunta con botones si no
    +question = gtk.MessageDialog(type=gtk.MESSAGE_QUESTION,
    +    buttons=gtk.BUTTONS_YES_NO, message_format="pregunta?")
    +# error con boton ok
    +error = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
    +    buttons=gtk.BUTTONS_OK, message_format="error!?!")
    +
    +# run bloquea hasta que se produzca un evento y devuelve el valor del evento
    +if info.run() == gtk.RESPONSE_DELETE_EVENT:
    +    print "si, es la unica senial que puede emitir, ya que no tiene botones"
    +# hay que esconder el dialogo
    +info.hide()
    +
    +# almacenamos el valor de retorno en una variable para controlar varios valores
    +response = warning.run()
    +warning.hide()
    +
    +if response == gtk.RESPONSE_OK:
    +    print "advertencia respondio aceptar"
    +elif response == gtk.RESPONSE_CANCEL:
    +    print "advertencia respondio cancel"
    +
    +response = question.run()
    +
    +if response == gtk.RESPONSE_YES:
    +    print "respondio si!"
    +elif response == gtk.RESPONSE_NO:
    +    print "respondio no :("
    +
    +question.hide()
    +
    +if error.run() == gtk.RESPONSE_OK:
    +    print "error OK"
    +
    +error.hide()
    +sys.exit(0)
    +
    +gtk.main()
     
    diff --git a/recetario/gui/gtk/emuladorterminal/index.html b/recetario/gui/gtk/emuladorterminal/index.html index dab7def9e..51889987e 100644 --- a/recetario/gui/gtk/emuladorterminal/index.html +++ b/recetario/gui/gtk/emuladorterminal/index.html @@ -33,7 +33,7 @@ scroll = gtk.Scrol'> - +Ir al contenido principal @@ -67,12 +67,12 @@ - + @@ -92,27 +92,27 @@

    Emulador De Terminal Con Gtk Y Vte

    Un ejemplo sobre cómo hacer una terminal visual al estilo gnome-terminal

    -/images/Recetario/Gui/Gtk/EmuladorTerminal/pyshell.png
    import gtk
    -import vte
    -
    -window = gtk.Window()
    -window.set_title("pyshell")
    -window.set_default_size(640, 480)
    -
    -scroll = gtk.ScrolledWindow()
    -
    -shell = vte.Terminal()
    -shell.connect("child-exited", gtk.main_quit)
    -shell.fork_command()
    -
    -scroll.add(shell)
    -
    -window.add(scroll)
    -
    -window.connect('delete-event', gtk.main_quit)
    -window.show_all()
    -
    -gtk.main()
    +/images/Recetario/Gui/Gtk/EmuladorTerminal/pyshell.png
    import gtk
    +import vte
    +
    +window = gtk.Window()
    +window.set_title("pyshell")
    +window.set_default_size(640, 480)
    +
    +scroll = gtk.ScrolledWindow()
    +
    +shell = vte.Terminal()
    +shell.connect("child-exited", gtk.main_quit)
    +shell.fork_command()
    +
    +scroll.add(shell)
    +
    +window.add(scroll)
    +
    +window.connect('delete-event', gtk.main_quit)
    +window.show_all()
    +
    +gtk.main()
     
    diff --git a/recetario/gui/gtk/entry/index.html b/recetario/gui/gtk/entry/index.html index 4f707ae9e..6518be690 100644 --- a/recetario/gui/gtk/entry/index.html +++ b/recetario/gui/gtk/entry/index.html @@ -30,7 +30,7 @@ class Ventana(gtk.Window): '''clase que define una ve"> - +Ir al contenido principal @@ -64,12 +64,12 @@ - + @@ -89,54 +89,54 @@

    Gtkentry

    Crear una ventana con un label, un campo de texto y mostrar el mensaje hola nombre con el valor ingresado en el entry.

    -/images/Recetario/Gui/Gtk/Entry/Entry.png
    import gtk
    -import sys
    -
    -class Ventana(gtk.Window):
    -    '''clase que define una ventana que saluda'''
    -
    -    def __init__(self):
    -        '''constructor, se llama al constructor de la clase padre'''
    -        gtk.Window.__init__(self)
    -
    -        # un tamanio muy chico para que se expanda el minimo tamanio necesario
    -        self.set_default_size(10, 10)
    -        self.label = gtk.Label("nombre")
    -        self.entry = gtk.Entry()
    -        self.set_title("entry")
    -        # 5 pixeles de espacio entre el borde de la ventana y el primer
    -        # contenedor
    -        self.set_border_width(5)
    -
    -        # 5 pixeles de espaciado entre cada widget
    -        hbox = gtk.HBox(spacing=5)
    -        hbox.pack_start(self.label)
    -        hbox.pack_start(self.entry)
    -
    -        self.add(hbox)
    -        hbox.show_all()
    -
    -        self.connect("delete-event", self.on_delete)
    -        # conectamos la senial activate (el usuario presiona enter)
    -        self.entry.connect("activate", self.on_entry_activate)
    -
    -    def on_delete(self, window, event):
    -        '''llamado cuando se cierra la ventana'''
    -        sys.exit(0)
    -
    -    def on_entry_activate(self, entry):
    -        '''llamada cuando se presiona enter en el entry, el primer elemento
    -        de toda senial de gtk es el elemento que emite la senial, asi que no
    -        necesitamos tener una referencia al elemento para interactuar con el'''
    -        message = gtk.MessageDialog(buttons=gtk.BUTTONS_OK,
    -            message_format="hola " + entry.get_text())
    -        message.run()
    -        message.hide()
    -
    -if __name__ == "__main__":
    -    hola = Ventana()
    -    hola.show()
    -    gtk.main()
    +/images/Recetario/Gui/Gtk/Entry/Entry.png
    import gtk
    +import sys
    +
    +class Ventana(gtk.Window):
    +    '''clase que define una ventana que saluda'''
    +
    +    def __init__(self):
    +        '''constructor, se llama al constructor de la clase padre'''
    +        gtk.Window.__init__(self)
    +
    +        # un tamanio muy chico para que se expanda el minimo tamanio necesario
    +        self.set_default_size(10, 10)
    +        self.label = gtk.Label("nombre")
    +        self.entry = gtk.Entry()
    +        self.set_title("entry")
    +        # 5 pixeles de espacio entre el borde de la ventana y el primer
    +        # contenedor
    +        self.set_border_width(5)
    +
    +        # 5 pixeles de espaciado entre cada widget
    +        hbox = gtk.HBox(spacing=5)
    +        hbox.pack_start(self.label)
    +        hbox.pack_start(self.entry)
    +
    +        self.add(hbox)
    +        hbox.show_all()
    +
    +        self.connect("delete-event", self.on_delete)
    +        # conectamos la senial activate (el usuario presiona enter)
    +        self.entry.connect("activate", self.on_entry_activate)
    +
    +    def on_delete(self, window, event):
    +        '''llamado cuando se cierra la ventana'''
    +        sys.exit(0)
    +
    +    def on_entry_activate(self, entry):
    +        '''llamada cuando se presiona enter en el entry, el primer elemento
    +        de toda senial de gtk es el elemento que emite la senial, asi que no
    +        necesitamos tener una referencia al elemento para interactuar con el'''
    +        message = gtk.MessageDialog(buttons=gtk.BUTTONS_OK,
    +            message_format="hola " + entry.get_text())
    +        message.run()
    +        message.hide()
    +
    +if __name__ == "__main__":
    +    hola = Ventana()
    +    hola.show()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/entrysolonumeros/index.html b/recetario/gui/gtk/entrysolonumeros/index.html index 18eb90c32..a192b0b68 100644 --- a/recetario/gui/gtk/entrysolonumeros/index.html +++ b/recetario/gui/gtk/entrysolonumeros/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + @@ -83,29 +83,29 @@

    Gtkentrysolonumeros

    Este ejemplo muestra como permitir el ingreso de solo números en un gtk.Entry, a través de la señal insert-text de gtk.Editable (clase de la que hereda gtk.Entry) y usando el método stop_emission de gobject para evitar que la señal se propague y sea manejada por el handler por defecto para la señal (que es el que inserta el carácter en el widget)

    -/images/Recetario/Gui/Gtk/EntrySoloNumeros/Only%20numbers.png
    '''ejemplo sobre solo dejar ingresar numeros en un campo de text
    -tambien sirve para cadenas de texto pegadas en el entry con ctrl-v
    -'''
    -
    -import re
    -import gtk
    -
    -ONLY_NUMBERS = re.compile('^[0-9]*$')
    -
    -def on_insert_text(editable, new_text, new_text_length, position):
    -    '''called when text is inserted on an entry'''
    -    if ONLY_NUMBERS.match(new_text) is None:
    -        editable.stop_emission('insert-text')
    -
    -entry = gtk.Entry()
    -entry.connect('insert-text', on_insert_text)
    -window = gtk.Window()
    -window.set_title('only numbers')
    -window.add(entry)
    -window.connect('delete-event', gtk.main_quit)
    -window.show_all()
    -
    -gtk.main()
    +/images/Recetario/Gui/Gtk/EntrySoloNumeros/Only%20numbers.png
    '''ejemplo sobre solo dejar ingresar numeros en un campo de text
    +tambien sirve para cadenas de texto pegadas en el entry con ctrl-v
    +'''
    +
    +import re
    +import gtk
    +
    +ONLY_NUMBERS = re.compile('^[0-9]*$')
    +
    +def on_insert_text(editable, new_text, new_text_length, position):
    +    '''called when text is inserted on an entry'''
    +    if ONLY_NUMBERS.match(new_text) is None:
    +        editable.stop_emission('insert-text')
    +
    +entry = gtk.Entry()
    +entry.connect('insert-text', on_insert_text)
    +window = gtk.Window()
    +window.set_title('only numbers')
    +window.add(entry)
    +window.connect('delete-event', gtk.main_quit)
    +window.show_all()
    +
    +gtk.main()
     
    diff --git a/recetario/gui/gtk/erorhandler/index.html b/recetario/gui/gtk/erorhandler/index.html index c2a254ee1..f26759276 100644 --- a/recetario/gui/gtk/erorhandler/index.html +++ b/recetario/gui/gtk/erorhandler/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    diff --git a/recetario/gui/gtk/errorhandler/index.html b/recetario/gui/gtk/errorhandler/index.html index 33220abc8..443b25164 100644 --- a/recetario/gui/gtk/errorhandler/index.html +++ b/recetario/gui/gtk/errorhandler/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + @@ -83,60 +83,60 @@

    Gtkerrorhandler

    Si aplicamos el decorador error_handler a una función, cuando lance una excepción, vamos a obtener un diálogo modal mostrandomos el traceback. Recomiendo usarlo solo para debug o versiones beta, un usuario no debería ver el traceback crudo.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -
    -import gtk
    -
    -def error_handler(function):
    -    def out(*args, **kwargs):
    -        try:
    -            return function(*args, **kwargs)
    -
    -        except KeyboardInterrupt:
    -            raise KeyboardInterrupt
    -
    -        except:
    -            from traceback import format_exc
    -            error = gtk.MessageDialog(
    -                type=gtk.MESSAGE_ERROR,
    -                buttons=gtk.BUTTONS_OK,
    -                message_format=''.join(format_exc())
    -                )
    -            error.set_title("Something went wrong!")
    -            if error.run() == gtk.RESPONSE_OK:
    -                print "Error OK"
    -            else:
    -                print "Error closed"
    -            error.hide()
    -    return out
    -
    -class Gui:
    -    def __init__(self):
    -        self.window = gtk.Window()
    -        self.window.set_default_size(200,200)
    -        self.window.set_title("Simple PyGTK example")
    -
    -        self.vbox = gtk.VBox()
    -
    -        self.button = gtk.Button("Click me!")
    -
    -        self.vbox.pack_start(self.button)
    -
    -        self.window.add(self.vbox)
    -
    -        self.button.connect("clicked", self.on_clicked)
    -        self.window.connect("destroy", lambda x: gtk.main_quit())
    -        self.window.show_all()
    -        self.window.show()
    -
    -    @error_handler
    -    def on_clicked(self, widget):
    -       raise IndexError
    -
    -if __name__ == "__main__":
    -    app = Gui()
    -    gtk.main()
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +
    +import gtk
    +
    +def error_handler(function):
    +    def out(*args, **kwargs):
    +        try:
    +            return function(*args, **kwargs)
    +
    +        except KeyboardInterrupt:
    +            raise KeyboardInterrupt
    +
    +        except:
    +            from traceback import format_exc
    +            error = gtk.MessageDialog(
    +                type=gtk.MESSAGE_ERROR,
    +                buttons=gtk.BUTTONS_OK,
    +                message_format=''.join(format_exc())
    +                )
    +            error.set_title("Something went wrong!")
    +            if error.run() == gtk.RESPONSE_OK:
    +                print "Error OK"
    +            else:
    +                print "Error closed"
    +            error.hide()
    +    return out
    +
    +class Gui:
    +    def __init__(self):
    +        self.window = gtk.Window()
    +        self.window.set_default_size(200,200)
    +        self.window.set_title("Simple PyGTK example")
    +
    +        self.vbox = gtk.VBox()
    +
    +        self.button = gtk.Button("Click me!")
    +
    +        self.vbox.pack_start(self.button)
    +
    +        self.window.add(self.vbox)
    +
    +        self.button.connect("clicked", self.on_clicked)
    +        self.window.connect("destroy", lambda x: gtk.main_quit())
    +        self.window.show_all()
    +        self.window.show()
    +
    +    @error_handler
    +    def on_clicked(self, widget):
    +       raise IndexError
    +
    +if __name__ == "__main__":
    +    app = Gui()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/funcionrunner/index.html b/recetario/gui/gtk/funcionrunner/index.html index 01f804caa..55f3f1716 100644 --- a/recetario/gui/gtk/funcionrunner/index.html +++ b/recetario/gui/gtk/funcionrunner/index.html @@ -28,7 +28,7 @@ c"> - +Ir al contenido principal @@ -62,12 +62,12 @@ - + @@ -97,153 +97,153 @@

    Gtkfuncionrunner

    func(*args, **kwargs) será llamada en un thread aparte el cuál será monitoreado periódicamente por su finalización. Una vez terminado llamará a callback pasándole una tupla cuyo primer elemento es True sí la función término con éxito y False sí la función lanzo una excepción. El segundo elemento de la tupla es el valor retornado por la función si tuvo éxito o la excepción lanzada en caso que haya fallado.

    Obviamente en la función esa no pueden correr código relacionado con gtk

    -
    '''example of a generic function to run a given function in a thread and call a
    -callback in the main thread with the result of the function'''
    -
    -import gtk
    -import glib
    -import time
    -import Queue
    -import urllib
    -import threading
    -
    -# this is the important function, copy this to your project to reuse it
    -def run_in_thread(callback, func, *args, **kwargs):
    -    '''run *func* in a thread with *args* and *kwargs* as arguments, when
    -    finished call callback with a two item tuple containing a boolean as first
    -    item informing if the function returned correctly and the returned value or
    -    the exception thrown as second item
    -    '''
    -
    -    queue = Queue.Queue()
    -
    -    def run():
    -        '''
    -        main function of the thread, run func with args and kwargs
    -        and get the result, call callback with the (True, result)
    -
    -        if an exception is thrown call callback with (False, exception)
    -        '''
    -        try:
    -            result = (True, func(*args, **kwargs))
    -        except Exception, ex:
    -            result = (False, ex)
    -
    -        queue.put(result)
    -
    -    def check():
    -        '''
    -        check if func finished
    -        '''
    -        try:
    -            result = queue.get(False, 0.1)
    -        except Queue.Empty:
    -            return True
    -
    -        callback(result)
    -        return False
    -
    -    glib.timeout_add_seconds(1, check)
    -    thread = threading.Thread(target=run)
    -    thread.setDaemon(True)
    -    thread.start()
    -
    -# everything below is just for the demo
    -def main():
    -    '''
    -    main function called when the module is run from the command line
    -    '''
    -
    -    def load_site(url):
    -        '''
    -        a demo function that loads the content of a url
    -        '''
    -        return urllib.urlopen(url).read()
    -
    -    class Display(gtk.Window):
    -        '''
    -        a window to display some content that loads slowly
    -        '''
    -
    -        def __init__(self, text, func, *args, **kwargs):
    -            gtk.Window.__init__(self)
    -            self.set_default_size(400, 300)
    -            self.set_title("display")
    -            self.set_border_width(2)
    -
    -            self.func = func
    -            self.args = args
    -            self.kwargs = kwargs
    -
    -            vbox = gtk.VBox(spacing=2)
    -            scroll = gtk.ScrolledWindow()
    -            self.text = gtk.TextView()
    -            self.text.get_buffer().set_text(text)
    -
    -            scroll.add(self.text)
    -
    -            vbox.pack_start(scroll, True, True)
    -
    -            self.loading = gtk.ProgressBar()
    -            self.is_loading = False
    -
    -            vbox.pack_start(self.loading, False)
    -
    -            buttons = gtk.HButtonBox()
    -            self.run = gtk.Button(stock=gtk.STOCK_EXECUTE)
    -            self.run.connect('clicked', self._on_run_clicked)
    -            buttons.pack_start(self.run)
    -
    -            vbox.pack_start(buttons, False)
    -
    -            self.add(vbox)
    -
    -            vbox.show_all()
    -            self.loading.hide()
    -            self.connect("delete-event", gtk.main_quit)
    -
    -        def _on_run_clicked(self, button):
    -            self.set_loading()
    -            run_in_thread(self._on_result_ready, self.func, *self.args,
    -                    **self.kwargs)
    -
    -        def set_loading(self, is_loading=True):
    -            '''
    -            set the window to the loading state
    -            '''
    -            self.is_loading = is_loading
    -            self.run.set_sensitive(not is_loading)
    -
    -            if is_loading:
    -                self.loading.show()
    -                glib.timeout_add(500, self._make_progress_bar_go_crazy)
    -            else:
    -                self.loading.hide()
    -
    -        def _on_result_ready(self, result):
    -            status, value = result
    -            self.set_loading(False)
    -
    -            if status:
    -                content = str(value)
    -            else:
    -                content = "exception running function: %s" % str(value)
    -
    -            self.text.get_buffer().set_text(content)
    -
    -        def _make_progress_bar_go_crazy(self):
    -            if self.is_loading:
    -                self.loading.pulse()
    -
    -            return self.is_loading
    -
    -    gtk.gdk.threads_init()
    -    Display("load the content of website", load_site,
    -            "http://marianoguerra.com.ar").show()
    -    gtk.main()
    -
    -if __name__ == '__main__':
    -    main()
    +
    '''example of a generic function to run a given function in a thread and call a
    +callback in the main thread with the result of the function'''
    +
    +import gtk
    +import glib
    +import time
    +import Queue
    +import urllib
    +import threading
    +
    +# this is the important function, copy this to your project to reuse it
    +def run_in_thread(callback, func, *args, **kwargs):
    +    '''run *func* in a thread with *args* and *kwargs* as arguments, when
    +    finished call callback with a two item tuple containing a boolean as first
    +    item informing if the function returned correctly and the returned value or
    +    the exception thrown as second item
    +    '''
    +
    +    queue = Queue.Queue()
    +
    +    def run():
    +        '''
    +        main function of the thread, run func with args and kwargs
    +        and get the result, call callback with the (True, result)
    +
    +        if an exception is thrown call callback with (False, exception)
    +        '''
    +        try:
    +            result = (True, func(*args, **kwargs))
    +        except Exception, ex:
    +            result = (False, ex)
    +
    +        queue.put(result)
    +
    +    def check():
    +        '''
    +        check if func finished
    +        '''
    +        try:
    +            result = queue.get(False, 0.1)
    +        except Queue.Empty:
    +            return True
    +
    +        callback(result)
    +        return False
    +
    +    glib.timeout_add_seconds(1, check)
    +    thread = threading.Thread(target=run)
    +    thread.setDaemon(True)
    +    thread.start()
    +
    +# everything below is just for the demo
    +def main():
    +    '''
    +    main function called when the module is run from the command line
    +    '''
    +
    +    def load_site(url):
    +        '''
    +        a demo function that loads the content of a url
    +        '''
    +        return urllib.urlopen(url).read()
    +
    +    class Display(gtk.Window):
    +        '''
    +        a window to display some content that loads slowly
    +        '''
    +
    +        def __init__(self, text, func, *args, **kwargs):
    +            gtk.Window.__init__(self)
    +            self.set_default_size(400, 300)
    +            self.set_title("display")
    +            self.set_border_width(2)
    +
    +            self.func = func
    +            self.args = args
    +            self.kwargs = kwargs
    +
    +            vbox = gtk.VBox(spacing=2)
    +            scroll = gtk.ScrolledWindow()
    +            self.text = gtk.TextView()
    +            self.text.get_buffer().set_text(text)
    +
    +            scroll.add(self.text)
    +
    +            vbox.pack_start(scroll, True, True)
    +
    +            self.loading = gtk.ProgressBar()
    +            self.is_loading = False
    +
    +            vbox.pack_start(self.loading, False)
    +
    +            buttons = gtk.HButtonBox()
    +            self.run = gtk.Button(stock=gtk.STOCK_EXECUTE)
    +            self.run.connect('clicked', self._on_run_clicked)
    +            buttons.pack_start(self.run)
    +
    +            vbox.pack_start(buttons, False)
    +
    +            self.add(vbox)
    +
    +            vbox.show_all()
    +            self.loading.hide()
    +            self.connect("delete-event", gtk.main_quit)
    +
    +        def _on_run_clicked(self, button):
    +            self.set_loading()
    +            run_in_thread(self._on_result_ready, self.func, *self.args,
    +                    **self.kwargs)
    +
    +        def set_loading(self, is_loading=True):
    +            '''
    +            set the window to the loading state
    +            '''
    +            self.is_loading = is_loading
    +            self.run.set_sensitive(not is_loading)
    +
    +            if is_loading:
    +                self.loading.show()
    +                glib.timeout_add(500, self._make_progress_bar_go_crazy)
    +            else:
    +                self.loading.hide()
    +
    +        def _on_result_ready(self, result):
    +            status, value = result
    +            self.set_loading(False)
    +
    +            if status:
    +                content = str(value)
    +            else:
    +                content = "exception running function: %s" % str(value)
    +
    +            self.text.get_buffer().set_text(content)
    +
    +        def _make_progress_bar_go_crazy(self):
    +            if self.is_loading:
    +                self.loading.pulse()
    +
    +            return self.is_loading
    +
    +    gtk.gdk.threads_init()
    +    Display("load the content of website", load_site,
    +            "http://marianoguerra.com.ar").show()
    +    gtk.main()
    +
    +if __name__ == '__main__':
    +    main()
     
    diff --git a/recetario/gui/gtk/gladeholamundooo/index.html b/recetario/gui/gtk/gladeholamundooo/index.html index ece4d86d6..8321691ab 100644 --- a/recetario/gui/gtk/gladeholamundooo/index.html +++ b/recetario/gui/gtk/gladeholamundooo/index.html @@ -27,7 +27,7 @@ gtk-glade-holamundo.glade Copiar el co'> - +Ir al contenido principal @@ -61,12 +61,12 @@ - + @@ -88,51 +88,51 @@

    Gtkgladeholamundooo

    Ejemplo que carga la interfaz de un archivo .glade y lo muestra, el archivo .glade puede tener cualquier contenido mientras la ventana tenga el nombre "ventana"

    gtk-glade-holamundo.glade

    Copiar el contenido siguiente a un archivo llamado gtk-glade-holamundo.glade el archivo fue editado con glade-3.

    -
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
    -<!--Generated with glade3 3.4.2 on Sat May 10 01:13:03 2008 -->
    -<glade-interface>
    -  <widget class="GtkWindow" id="ventana">
    -    <property name="title" translatable="yes">hola mundo glade</property>
    -    <property name="window_position">GTK_WIN_POS_CENTER</property>
    -    <property name="default_width">200</property>
    -    <property name="default_height">200</property>
    -    <signal name="delete_event" handler="on_ventana_delete_event"/>
    -    <child>
    -      <widget class="GtkLabel" id="label">
    -        <property name="visible">True</property>
    -        <property name="label" translatable="yes">hola pyar!</property>
    -      </widget>
    -    </child>
    -  </widget>
    -</glade-interface>
    +
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
    +<!--Generated with glade3 3.4.2 on Sat May 10 01:13:03 2008 -->
    +<glade-interface>
    +  <widget class="GtkWindow" id="ventana">
    +    <property name="title" translatable="yes">hola mundo glade</property>
    +    <property name="window_position">GTK_WIN_POS_CENTER</property>
    +    <property name="default_width">200</property>
    +    <property name="default_height">200</property>
    +    <signal name="delete_event" handler="on_ventana_delete_event"/>
    +    <child>
    +      <widget class="GtkLabel" id="label">
    +        <property name="visible">True</property>
    +        <property name="label" translatable="yes">hola pyar!</property>
    +      </widget>
    +    </child>
    +  </widget>
    +</glade-interface>
     

    El código para el ejemplo es el siguiente:

    -
    import gtk
    -import sys
    -import gtk.glade
    -
    -class HolaMundo(object):
    -    '''clase que muestra un hola mundo desde un archivo glade'''
    -
    -    def __init__(self):
    -        '''constructor'''
    -        self.tree = gtk.glade.XML("gtk-glade-holamundo.glade")
    -        self.tree.signal_autoconnect(self)
    -        self.window = self.tree.get_widget("ventana")
    -
    -    def on_ventana_delete_event(self, window, event):
    -        '''callback llamado cuando se cierra la ventana'''
    -        sys.exit(0)
    -
    -    def show(self):
    -        '''muestra la ventana principal'''
    -        self.window.show_all()
    -
    -if __name__ == "__main__":
    -    hola = HolaMundo()
    -    hola.show()
    -    gtk.main()
    +
    import gtk
    +import sys
    +import gtk.glade
    +
    +class HolaMundo(object):
    +    '''clase que muestra un hola mundo desde un archivo glade'''
    +
    +    def __init__(self):
    +        '''constructor'''
    +        self.tree = gtk.glade.XML("gtk-glade-holamundo.glade")
    +        self.tree.signal_autoconnect(self)
    +        self.window = self.tree.get_widget("ventana")
    +
    +    def on_ventana_delete_event(self, window, event):
    +        '''callback llamado cuando se cierra la ventana'''
    +        sys.exit(0)
    +
    +    def show(self):
    +        '''muestra la ventana principal'''
    +        self.window.show_all()
    +
    +if __name__ == "__main__":
    +    hola = HolaMundo()
    +    hola.show()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/grid/index.html b/recetario/gui/gtk/grid/index.html index 2a7c6b8ca..08b536354 100644 --- a/recetario/gui/gtk/grid/index.html +++ b/recetario/gui/gtk/grid/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/recetario/gui/gtk/hbox/index.html b/recetario/gui/gtk/hbox/index.html index d92120367..dfb989660 100644 --- a/recetario/gui/gtk/hbox/index.html +++ b/recetario/gui/gtk/hbox/index.html @@ -30,7 +30,7 @@ class Ventana(gtk.Window): '''clase que define una ventana que saluda'''"> - +Ir al contenido principal @@ -64,12 +64,12 @@ - + @@ -89,39 +89,39 @@

    Gtkhbox

    Ejemplo que muestra el uso de hbox (cajas horizontales) para ordenar elementos de forma horizontal.

    -/images/Recetario/Gui/Gtk/HBox/hbox.png
    import gtk
    -import sys
    -
    -class Ventana(gtk.Window):
    -    '''clase que define una ventana que saluda'''
    -
    -    def __init__(self):
    -        '''constructor, se llama al constructor de la clase padre'''
    -        gtk.Window.__init__(self)
    -
    -        self.set_default_size(200, 200)
    -        self.set_title("hbox")
    -        # creamos una caja horizontal que contiene elementos
    -        # de manera horizontal
    -        self.hbox = gtk.HBox()
    -        # agregamos tres elementos
    -        self.hbox.pack_start(gtk.Label("uno"))
    -        self.hbox.pack_start(gtk.Label("dos"))
    -        self.hbox.pack_start(gtk.Label("tres"))
    -
    -        self.add(self.hbox)
    -        self.hbox.show_all()
    -
    -        self.connect("delete-event", self.on_delete)
    -
    -    def on_delete(self, window, event):
    -        '''llamado cuando se cierra la ventana'''
    -        sys.exit(0)
    -
    -if __name__ == "__main__":
    -    ventana = Ventana()
    -    ventana.show()
    -    gtk.main()
    +/images/Recetario/Gui/Gtk/HBox/hbox.png
    import gtk
    +import sys
    +
    +class Ventana(gtk.Window):
    +    '''clase que define una ventana que saluda'''
    +
    +    def __init__(self):
    +        '''constructor, se llama al constructor de la clase padre'''
    +        gtk.Window.__init__(self)
    +
    +        self.set_default_size(200, 200)
    +        self.set_title("hbox")
    +        # creamos una caja horizontal que contiene elementos
    +        # de manera horizontal
    +        self.hbox = gtk.HBox()
    +        # agregamos tres elementos
    +        self.hbox.pack_start(gtk.Label("uno"))
    +        self.hbox.pack_start(gtk.Label("dos"))
    +        self.hbox.pack_start(gtk.Label("tres"))
    +
    +        self.add(self.hbox)
    +        self.hbox.show_all()
    +
    +        self.connect("delete-event", self.on_delete)
    +
    +    def on_delete(self, window, event):
    +        '''llamado cuando se cierra la ventana'''
    +        sys.exit(0)
    +
    +if __name__ == "__main__":
    +    ventana = Ventana()
    +    ventana.show()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/holamundo/index.html b/recetario/gui/gtk/holamundo/index.html index 655c5c807..e069c5229 100644 --- a/recetario/gui/gtk/holamundo/index.html +++ b/recetario/gui/gtk/holamundo/index.html @@ -32,7 +32,7 @@ # seteamos el tamanio de la ventana window.set_default_size(200,"> - +Ir al contenido principal @@ -66,12 +66,12 @@ - + @@ -91,35 +91,35 @@

    Gtkholamundo

    Crea y muestra una ventana que muestra el famoso mensaje hola mundo.

    -/images/Recetario/Gui/Gtk/HolaMundo/Hola%20mundo.png
    import gtk
    -import sys
    -
    -# se crea la ventana
    -window = gtk.Window()
    -# seteamos el tamanio de la ventana
    -window.set_default_size(200, 200)
    -# se crea la etiqueta que va a mostrar el mensaje
    -label = gtk.Label("Hola pyar!")
    -# se setea el el titulo de la ventana
    -window.set_title("hola mundo")
    -# agregamos el label a la ventana
    -window.add(label)
    -# mostramos la ventana y todo lo que contiene
    -window.show_all()
    -
    -def on_window_close(window, event):
    -    '''este metodo es llamado cuando se aprieta la equis para cerrar la
    -    ventana'''
    -    # cerramos el programa retornando 0 (exito)
    -    sys.exit(0)
    -
    -# conectamos la senial delete-event que es emitida cuando se presiona la
    -# equis en la ventana
    -window.connect("delete-event", on_window_close)
    -
    -# llamamos al main loop para que muestre la ventana y
    -# procese los eventos
    -gtk.main()
    +/images/Recetario/Gui/Gtk/HolaMundo/Hola%20mundo.png
    import gtk
    +import sys
    +
    +# se crea la ventana
    +window = gtk.Window()
    +# seteamos el tamanio de la ventana
    +window.set_default_size(200, 200)
    +# se crea la etiqueta que va a mostrar el mensaje
    +label = gtk.Label("Hola pyar!")
    +# se setea el el titulo de la ventana
    +window.set_title("hola mundo")
    +# agregamos el label a la ventana
    +window.add(label)
    +# mostramos la ventana y todo lo que contiene
    +window.show_all()
    +
    +def on_window_close(window, event):
    +    '''este metodo es llamado cuando se aprieta la equis para cerrar la
    +    ventana'''
    +    # cerramos el programa retornando 0 (exito)
    +    sys.exit(0)
    +
    +# conectamos la senial delete-event que es emitida cuando se presiona la
    +# equis en la ventana
    +window.connect("delete-event", on_window_close)
    +
    +# llamamos al main loop para que muestre la ventana y
    +# procese los eventos
    +gtk.main()
     
    diff --git a/recetario/gui/gtk/holamundooo/index.html b/recetario/gui/gtk/holamundooo/index.html index f19f8c6ef..3e1cb5637 100644 --- a/recetario/gui/gtk/holamundooo/index.html +++ b/recetario/gui/gtk/holamundooo/index.html @@ -33,7 +33,7 @@ def __init__(self): "> - +Ir al contenido principal @@ -67,12 +67,12 @@ - + @@ -92,32 +92,32 @@

    Gtkholamundooo

    Ejemplo que hace lo mismo que GtkHolaMundo pero orientado a objetos.

    -/images/Recetario/Gui/Gtk/HolaMundoOO/Hola%20mundo%20oo.png
    import gtk
    -import sys
    -
    -class HolaMundo(gtk.Window):
    -    '''clase que define una ventana que saluda'''
    -
    -    def __init__(self):
    -        '''constructor, se llama al constructor de la clase padre'''
    -        gtk.Window.__init__(self)
    -
    -        self.set_default_size(200, 200)
    -        self.label = gtk.Label("Hola pyar")
    -        self.set_title("hola mundo oo")
    -        self.add(self.label)
    -        self.label.show()
    -
    -        self.connect("delete-event", self.on_delete)
    -
    -    def on_delete(self, window, event):
    -        '''llamado cuando se cierra la ventana'''
    -        sys.exit(0)
    -
    -if __name__ == "__main__":
    -    hola = HolaMundo()
    -    hola.show()
    -    gtk.main()
    +/images/Recetario/Gui/Gtk/HolaMundoOO/Hola%20mundo%20oo.png
    import gtk
    +import sys
    +
    +class HolaMundo(gtk.Window):
    +    '''clase que define una ventana que saluda'''
    +
    +    def __init__(self):
    +        '''constructor, se llama al constructor de la clase padre'''
    +        gtk.Window.__init__(self)
    +
    +        self.set_default_size(200, 200)
    +        self.label = gtk.Label("Hola pyar")
    +        self.set_title("hola mundo oo")
    +        self.add(self.label)
    +        self.label.show()
    +
    +        self.connect("delete-event", self.on_delete)
    +
    +    def on_delete(self, window, event):
    +        '''llamado cuando se cierra la ventana'''
    +        sys.exit(0)
    +
    +if __name__ == "__main__":
    +    hola = HolaMundo()
    +    hola.show()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/labelconcolor/index.html b/recetario/gui/gtk/labelconcolor/index.html index 37116f9ca..a044a5899 100644 --- a/recetario/gui/gtk/labelconcolor/index.html +++ b/recetario/gui/gtk/labelconcolor/index.html @@ -28,7 +28,7 @@ window = "> - +Ir al contenido principal @@ -62,12 +62,12 @@ - + @@ -88,17 +88,17 @@

    Gtk Label Con Color

    Ejemplo de cómo cambiar el color de un label sin usar pango markup

    Observaciones: sí se comenta label.realize() el color que se imprime no es el que seteamos sino el por defecto.

    -
    import gtk
    -
    -window = gtk.Window()
    -label = gtk.Label("label")
    -window.add(label)
    -window.connect('delete-event', gtk.main_quit)
    -label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#f00'))
    -label.realize()
    -print label.style.fg[gtk.STATE_NORMAL]
    -window.show_all()
    -gtk.main()
    +
    import gtk
    +
    +window = gtk.Window()
    +label = gtk.Label("label")
    +window.add(label)
    +window.connect('delete-event', gtk.main_quit)
    +label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#f00'))
    +label.realize()
    +print label.style.fg[gtk.STATE_NORMAL]
    +window.show_all()
    +gtk.main()
     
    diff --git a/recetario/gui/gtk/listview/index.html b/recetario/gui/gtk/listview/index.html index b19345f3a..a3ab7ac29 100644 --- a/recetario/gui/gtk/listview/index.html +++ b/recetario/gui/gtk/listview/index.html @@ -31,7 +31,7 @@ def __init__(self, width=640, height=480, title="gtk list example", "> - +Ir al contenido principal @@ -65,12 +65,12 @@ - + @@ -89,75 +89,75 @@

    Gtk Listview

    - /images/Recetario/Gui/Gtk/ListView/gtklistexample.png
    import gtk
    -import gobject
    -
    -class GtkListExample(gtk.Window):
    -    '''clase que representa una ventana con una lista'''
    -
    -    def __init__(self, width=640, height=480, title="gtk list example",
    -            on_exit=gtk.main_quit):
    -        '''constructor'''
    -        # llamamos al constructor de la clase padre
    -        gtk.Window.__init__(self)
    -
    -        # establecemos el tamanio
    -        self.set_default_size(width, height)
    -        # establecemos el titulo
    -        self.set_title(title)
    -
    -        # creamos el modelo de cada fila
    -        # el modelo y la vista se crean separadamente y se relacionan despues
    -        # https://es.wikipedia.org/wiki/Modelo_Vista_Controlador
    -        self.model = gtk.ListStore(str, int, bool)
    -        # creamos el widget que va a mostrar la lista y le pasamos el modelo
    -        self.list = gtk.TreeView(self.model)
    -
    -        # creamos los objetos que van a renderizar los atributos
    -        textrenderer = gtk.CellRendererText()
    -        # seteamos una propiedad
    -        textrenderer.set_property("xalign", 0.5)
    -        # un renderer para renderizar booleanos como checkbox
    -        boolrenderer = gtk.CellRendererToggle()
    -
    -        # creamos las columnas de la lista
    -        # no necesariamente todos los elementos del modelo se deben mostrar
    -        # tampoco es necesario que se muestren en el orden del modelo, por
    -        # eso creamos las columnas para decirle que elementos del modelo
    -        # mostrar y como mostrarlos
    -        column1 = gtk.TreeViewColumn("nombre", textrenderer, text=0)
    -        column1.set_expand(True)
    -
    -        column2 = gtk.TreeViewColumn("edad", textrenderer, text=1)
    -        column2.set_expand(True)
    -
    -        column3 = gtk.TreeViewColumn("algo", boolrenderer, active=2)
    -        column3.set_expand(True)
    -
    -        # agregamos las columnas
    -        self.list.append_column(column1)
    -        self.list.append_column(column2)
    -        self.list.append_column(column3)
    -
    -        # agregamos la lista a la ventana
    -        self.add(self.list)
    -        # mostramos el widget
    -        self.list.show_all()
    -        # conectamos un manejador para cuando aprieten cerrar
    -        self.connect('delete-event', on_exit)
    -
    -    def add_item(self, string, number, boolean):
    -        # agregamos una fila al modelo
    -        self.model.append((string, number, boolean))
    -
    -if __name__ == "__main__":
    -    window = GtkListExample()
    -    window.show()
    -    window.add_item("bob", 26, True)
    -    window.add_item("patricio", 24, True)
    -    window.add_item("arenita", 27, False)
    -
    -    gtk.main()
    +    /images/Recetario/Gui/Gtk/ListView/gtklistexample.png
    import gtk
    +import gobject
    +
    +class GtkListExample(gtk.Window):
    +    '''clase que representa una ventana con una lista'''
    +
    +    def __init__(self, width=640, height=480, title="gtk list example",
    +            on_exit=gtk.main_quit):
    +        '''constructor'''
    +        # llamamos al constructor de la clase padre
    +        gtk.Window.__init__(self)
    +
    +        # establecemos el tamanio
    +        self.set_default_size(width, height)
    +        # establecemos el titulo
    +        self.set_title(title)
    +
    +        # creamos el modelo de cada fila
    +        # el modelo y la vista se crean separadamente y se relacionan despues
    +        # https://es.wikipedia.org/wiki/Modelo_Vista_Controlador
    +        self.model = gtk.ListStore(str, int, bool)
    +        # creamos el widget que va a mostrar la lista y le pasamos el modelo
    +        self.list = gtk.TreeView(self.model)
    +
    +        # creamos los objetos que van a renderizar los atributos
    +        textrenderer = gtk.CellRendererText()
    +        # seteamos una propiedad
    +        textrenderer.set_property("xalign", 0.5)
    +        # un renderer para renderizar booleanos como checkbox
    +        boolrenderer = gtk.CellRendererToggle()
    +
    +        # creamos las columnas de la lista
    +        # no necesariamente todos los elementos del modelo se deben mostrar
    +        # tampoco es necesario que se muestren en el orden del modelo, por
    +        # eso creamos las columnas para decirle que elementos del modelo
    +        # mostrar y como mostrarlos
    +        column1 = gtk.TreeViewColumn("nombre", textrenderer, text=0)
    +        column1.set_expand(True)
    +
    +        column2 = gtk.TreeViewColumn("edad", textrenderer, text=1)
    +        column2.set_expand(True)
    +
    +        column3 = gtk.TreeViewColumn("algo", boolrenderer, active=2)
    +        column3.set_expand(True)
    +
    +        # agregamos las columnas
    +        self.list.append_column(column1)
    +        self.list.append_column(column2)
    +        self.list.append_column(column3)
    +
    +        # agregamos la lista a la ventana
    +        self.add(self.list)
    +        # mostramos el widget
    +        self.list.show_all()
    +        # conectamos un manejador para cuando aprieten cerrar
    +        self.connect('delete-event', on_exit)
    +
    +    def add_item(self, string, number, boolean):
    +        # agregamos una fila al modelo
    +        self.model.append((string, number, boolean))
    +
    +if __name__ == "__main__":
    +    window = GtkListExample()
    +    window.show()
    +    window.add_item("bob", 26, True)
    +    window.add_item("patricio", 24, True)
    +    window.add_item("arenita", 27, False)
    +
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/menu/index.html b/recetario/gui/gtk/menu/index.html index 0dc810a2f..31b8bc9ce 100644 --- a/recetario/gui/gtk/menu/index.html +++ b/recetario/gui/gtk/menu/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/recetario/gui/gtk/multithread/index.html b/recetario/gui/gtk/multithread/index.html index dc9757a59..a3057c134 100644 --- a/recetario/gui/gtk/multithread/index.html +++ b/recetario/gui/gtk/multithread/index.html @@ -30,7 +30,7 @@ import gobject import threa"> - +Ir al contenido principal @@ -64,12 +64,12 @@ - + @@ -89,67 +89,67 @@

    Gtkmultithread

    Ejemplo de cómo manipular la api desde múltiples threads sin usar locks. Compare con el otro ejemplo que no utiliza colas.

    -
    import gtk
    -import time
    -import Queue
    -import random
    -import gobject
    -import threading
    -
    -TEXTS = ['eggs', 'spam', 'pyar', 'gtk']
    -
    -class Molesto(threading.Thread):
    -    '''un thread que quiere molestar el main thread'''
    -
    -    def __init__(self, label, cola):
    -        threading.Thread.__init__(self)
    -        self.setDaemon(True)
    -        self.label = label # no usar en este thread!
    -        self.cola = cola
    -
    -    def run(self):
    -        '''metodo principal del thread, duerme un tiempo aleatorio y despues
    -        pone algo en la cola para que el main thread lo haga'''
    -
    -        while True:
    -            time.sleep(random.random() * 5)
    -            texto = self.getName() + ' ' + random.choice(TEXTS)
    -            print self.getName(), 'escribiendo', texto
    -            self.cola.put((self.label.set_text, (texto,), {}))
    -
    -class Ventana(gtk.Window):
    -    '''ventana con un label, ninguna locura'''
    -
    -    def __init__(self):
    -        gtk.Window.__init__(self)
    -        self.set_default_size(640, 480)
    -        self.set_title('gtk con threads')
    -        self.label = gtk.Label('')
    -        self.add(self.label)
    -        self.label.show()
    -
    -
    -queue = Queue.Queue()
    -def queue_manager():
    -    try:
    -        while True:
    -            method, args, kwargs = queue.get(True, 0.1)
    -            print 'ejecutando', method.__name__, 'con', args, kwargs
    -            method(*args, **kwargs)
    -    except Queue.Empty:
    -        pass
    -
    -    return True
    -
    -if __name__ == '__main__':
    -    gtk.gdk.threads_init()
    -    gobject.timeout_add(200, queue_manager)
    -    ventana = Ventana()
    -    ventana.show()
    -    threads = [Molesto(ventana.label, queue) for x in range(10)]
    -    for thread in threads:
    -        thread.start()
    -    gtk.main()
    +
    import gtk
    +import time
    +import Queue
    +import random
    +import gobject
    +import threading
    +
    +TEXTS = ['eggs', 'spam', 'pyar', 'gtk']
    +
    +class Molesto(threading.Thread):
    +    '''un thread que quiere molestar el main thread'''
    +
    +    def __init__(self, label, cola):
    +        threading.Thread.__init__(self)
    +        self.setDaemon(True)
    +        self.label = label # no usar en este thread!
    +        self.cola = cola
    +
    +    def run(self):
    +        '''metodo principal del thread, duerme un tiempo aleatorio y despues
    +        pone algo en la cola para que el main thread lo haga'''
    +
    +        while True:
    +            time.sleep(random.random() * 5)
    +            texto = self.getName() + ' ' + random.choice(TEXTS)
    +            print self.getName(), 'escribiendo', texto
    +            self.cola.put((self.label.set_text, (texto,), {}))
    +
    +class Ventana(gtk.Window):
    +    '''ventana con un label, ninguna locura'''
    +
    +    def __init__(self):
    +        gtk.Window.__init__(self)
    +        self.set_default_size(640, 480)
    +        self.set_title('gtk con threads')
    +        self.label = gtk.Label('')
    +        self.add(self.label)
    +        self.label.show()
    +
    +
    +queue = Queue.Queue()
    +def queue_manager():
    +    try:
    +        while True:
    +            method, args, kwargs = queue.get(True, 0.1)
    +            print 'ejecutando', method.__name__, 'con', args, kwargs
    +            method(*args, **kwargs)
    +    except Queue.Empty:
    +        pass
    +
    +    return True
    +
    +if __name__ == '__main__':
    +    gtk.gdk.threads_init()
    +    gobject.timeout_add(200, queue_manager)
    +    ventana = Ventana()
    +    ventana.show()
    +    threads = [Molesto(ventana.label, queue) for x in range(10)]
    +    for thread in threads:
    +        thread.start()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/multithread2/index.html b/recetario/gui/gtk/multithread2/index.html index 3ec5d4936..f7612e234 100644 --- a/recetario/gui/gtk/multithread2/index.html +++ b/recetario/gui/gtk/multithread2/index.html @@ -35,7 +35,7 @@ "> - + Ir al contenido principal @@ -69,12 +69,12 @@ - +
    @@ -94,57 +94,57 @@

    Multithread2

    Otro ejemplo del uso de threads con gtk, compare con el otro ejemplo que utiliza colas

    -
    import time
    -import random
    -import threading
    -
    -import gtk
    -import gtk.gdk
    -
    -
    -texts = ['eggs', 'spam', 'pyar', 'gtk']
    -
    -class molesto(threading.Thread):
    -    '''un thread que quiere molestar el main thread'''
    -
    -    def __init__(self, label):
    -        threading.Thread.__init__(self)
    -        self.setDaemon(True)
    -        self.label = label
    -
    -    def run(self):
    -        '''metodo principal del thread, duerme un tiempo aleatorio y despues
    -        cambia el Label'''
    -
    -        while True:
    -            time.sleep(random.random() * 5)
    -            texto = self.getName() + ' ' + random.choice(texts)
    -
    -            gtk.gdk.threads_enter()
    -            # zona critica de gtk
    -            print self.getName(), 'escribiendo', texto
    -            self.label.set_text(texto)
    -            gtk.gdk.threads_leave()
    -
    -class ventana(gtk.Window):
    -    '''ventana con un label, ninguna locura'''
    -
    -    def __init__(self):
    -        gtk.Window.__init__(self)
    -        self.set_default_size(640, 480)
    -        self.set_title('gtk con threads')
    -        self.label = gtk.Label('')
    -        self.add(self.label)
    -        self.label.show()
    -
    -if __name__ == '__main__':
    -    gtk.gdk.threads_init()
    -    ventana = ventana()
    -    ventana.show()
    -    threads = [molesto(ventana.label) for x in range(10)]
    -    for thread in threads:
    -        thread.start()
    -    gtk.main()
    +
    import time
    +import random
    +import threading
    +
    +import gtk
    +import gtk.gdk
    +
    +
    +texts = ['eggs', 'spam', 'pyar', 'gtk']
    +
    +class molesto(threading.Thread):
    +    '''un thread que quiere molestar el main thread'''
    +
    +    def __init__(self, label):
    +        threading.Thread.__init__(self)
    +        self.setDaemon(True)
    +        self.label = label
    +
    +    def run(self):
    +        '''metodo principal del thread, duerme un tiempo aleatorio y despues
    +        cambia el Label'''
    +
    +        while True:
    +            time.sleep(random.random() * 5)
    +            texto = self.getName() + ' ' + random.choice(texts)
    +
    +            gtk.gdk.threads_enter()
    +            # zona critica de gtk
    +            print self.getName(), 'escribiendo', texto
    +            self.label.set_text(texto)
    +            gtk.gdk.threads_leave()
    +
    +class ventana(gtk.Window):
    +    '''ventana con un label, ninguna locura'''
    +
    +    def __init__(self):
    +        gtk.Window.__init__(self)
    +        self.set_default_size(640, 480)
    +        self.set_title('gtk con threads')
    +        self.label = gtk.Label('')
    +        self.add(self.label)
    +        self.label.show()
    +
    +if __name__ == '__main__':
    +    gtk.gdk.threads_init()
    +    ventana = ventana()
    +    ventana.show()
    +    threads = [molesto(ventana.label) for x in range(10)]
    +    for thread in threads:
    +        thread.start()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/printnongtk/index.html b/recetario/gui/gtk/printnongtk/index.html index 96c4ee554..63825fa7b 100644 --- a/recetario/gui/gtk/printnongtk/index.html +++ b/recetario/gui/gtk/printnongtk/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +
    @@ -86,20 +86,20 @@

    Gtkprintnongtk

    Este ejemplo muestra como usar gtk para mostrar el diálogo de imprimir pero sin usar el main loop.

    Es útil para aplicaciones no gtk que solo quieren usar el diálogo de impresión pero tienen otro main loop que no es el de gtk.

    Explicación: Lo que hacemos después de mostrar el diálogo es procesar los eventos de gtk mientras haya eventos pendientes, luego seguimos en nuestra aplicación normalmente.

    -
    import gtk
    -import time
    -
    -po = gtk.PrintOperation()
    -pa = gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG
    -po.run(pa)
    -
    -while gtk.events_pending():
    -    gtk.main_iteration(True)
    -
    -print 'y seguimos como si nada'
    -print 'esperamos 3 segundos'
    -time.sleep(3)
    -print 'chau'
    +
    import gtk
    +import time
    +
    +po = gtk.PrintOperation()
    +pa = gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG
    +po.run(pa)
    +
    +while gtk.events_pending():
    +    gtk.main_iteration(True)
    +
    +print 'y seguimos como si nada'
    +print 'esperamos 3 segundos'
    +time.sleep(3)
    +print 'chau'
     
    /images/Recetario/Gui/Gtk/PrintNonGtk/Imprimir.png
    diff --git a/recetario/gui/gtk/richtext/index.html b/recetario/gui/gtk/richtext/index.html index 929d7a396..7d0ce36d0 100644 --- a/recetario/gui/gtk/richtext/index.html +++ b/recetario/gui/gtk/richtext/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -84,166 +84,166 @@

    Gtkrichtext

    Ejemplo sobre cómo mostrar texto con formato en un gtk.TextView, se crea una clase que extiende gtk.TextBuffer para facilitar la inserción de texto con formato.

    -
    '''a module that contains a class to insert rich text into a textview'''
    -
    -import gtk
    -import pango
    -
    -class RichBuffer(gtk.TextBuffer):
    -    '''a buffer that makes it easy to manipulate a gtk textview with
    -    rich text'''
    -
    -    def __init__(self):
    -        '''constructor'''
    -        gtk.TextBuffer.__init__(self)
    -
    -        self.colormap = gtk.gdk.colormap_get_system()
    -
    -        self.fg_tags = {}
    -        self.bg_tags = {}
    -        self.font_tags = {}
    -        self.size_tags = {}
    -        self.bold_tag = self.create_tag("bold", weight=pango.WEIGHT_BOLD)
    -        self.italic_tag = self.create_tag("italic", style=pango.STYLE_ITALIC)
    -        self.underline_tag = self.create_tag("underline",
    -            underline=pango.UNDERLINE_SINGLE)
    -        self.strike_tag = self.create_tag("strike", strikethrough=True)
    -
    -    def put_text(self, text, fg_color=None, bg_color=None, font=None, size=None,
    -        bold=False, italic=False, underline=False, strike=False):
    -        '''insert text at the current position with the style defined by the
    -        optional parameters'''
    -        tags = self._parse_tags(fg_color, bg_color, font, size, bold, italic,
    -            underline, strike)
    -        iterator = self.get_iter_at_mark(self.get_insert())
    -        self._insert(iterator, text, tags)
    -
    -    def _insert(self, iterator, text, tags=None):
    -        '''insert text at the current position with the style defined by the
    -        optional parameters'''
    -        if tags is not None:
    -            self.insert_with_tags(iterator, text, *tags)
    -        else:
    -            self.insert(iterator, text)
    -
    -    def _parse_tags(self, fg_color=None, bg_color=None, font=None, size=None,
    -        bold=False, italic=False, underline=False, strike=False):
    -        '''parse the parameters and return a list of tags to apply that
    -        format
    -        '''
    -        tags = []
    -
    -        if fg_color:
    -            tag = self._parse_fg(fg_color)
    -            if tag:
    -                tags.append(tag)
    -
    -        if bg_color:
    -            tag = self._parse_bg(bg_color)
    -            if tag:
    -                tags.append(tag)
    -
    -        if font:
    -            tag = self._parse_font(font)
    -            if tag:
    -                tags.append(tag)
    -
    -        if size:
    -            tag = self._parse_size(size)
    -            if tag:
    -                tags.append(tag)
    -
    -        if bold:
    -            tags.append(self.bold_tag)
    -
    -        if italic:
    -            tags.append(self.italic_tag)
    -
    -        if underline:
    -            tags.append(self.underline_tag)
    -
    -        if strike:
    -            tags.append(self.strike_tag)
    -
    -        return tags
    -
    -    def _parse_fg(self, value):
    -        '''parse the foreground color and return a tag'''
    -        if value in self.fg_tags:
    -            return self.fg_tags[value]
    -
    -        try:
    -            color = gtk.gdk.color_parse(value)
    -            self.colormap.alloc_color(color)
    -        except ValueError:
    -            return None
    -
    -        color_tag = self.create_tag('fg_' + value[1:], foreground_gdk=color)
    -        self.fg_tags[value] = color_tag
    -
    -        return color_tag
    -
    -    def _parse_bg(self, value):
    -        '''parse the background color and return a tag'''
    -        if value in self.bg_tags:
    -            return self.bg_tags[value]
    -
    -        try:
    -            color = gtk.gdk.color_parse(value)
    -            self.colormap.alloc_color(color)
    -        except ValueError:
    -            return None
    -
    -        color_tag = self.create_tag('bg_' + value[1:], background_gdk=color)
    -        self.bg_tags[value] = color_tag
    -
    -        return color_tag
    -
    -    def _parse_font(self, value):
    -        '''parse the font and return a tag'''
    -        if value in self.font_tags:
    -            return self.font_tags[value]
    -
    -        font_tag = self.create_tag('font_' + value.replace(' ', '_'),
    -            font=value)
    -        self.font_tags[value] = font_tag
    -
    -        return font_tag
    -
    -    def _parse_size(self, value):
    -        '''parse the font size and return a tag'''
    -        if value in self.size_tags:
    -            return self.size_tags[value]
    -
    -        size_tag = self.create_tag('size_' + str(value), size_points=value)
    -        self.size_tags[value] = size_tag
    -        return size_tag
    -
    -def test():
    -    '''do some tests with the buffer'''
    -    import sys
    -    def on_close(widget, event):
    -        '''method called when the window is closed'''
    -        sys.exit(0)
    -
    -    window = gtk.Window()
    -    window.set_default_size(640, 480)
    -    window.connect('delete-event', on_close)
    -    textview = gtk.TextView()
    -    buff = RichBuffer()
    -    textview.set_buffer(buff)
    -    window.add(textview)
    -    window.show_all()
    -    buff.put_text('buenas, como va? ', '#CCCCCC', '#000000', 'Arial', 12)
    -    buff.put_text('esto es una prueba\n', '#CC0000', '#AAAAAA', 'Purisa', 14)
    -    buff.put_text('un poco de formato\n', '#00CC00', '#FFFFFF', 'Andale Mono',
    -        8, True, True, True, True)
    -    buff.put_text('un poco mas\n', '#CCCCCC', '#0000CC', 'Andale Mono', 16,
    -        False, True, False, True)
    -    gtk.main()
    -
    -if __name__ == '__main__':
    -    test()
    +
    '''a module that contains a class to insert rich text into a textview'''
    +
    +import gtk
    +import pango
    +
    +class RichBuffer(gtk.TextBuffer):
    +    '''a buffer that makes it easy to manipulate a gtk textview with
    +    rich text'''
    +
    +    def __init__(self):
    +        '''constructor'''
    +        gtk.TextBuffer.__init__(self)
    +
    +        self.colormap = gtk.gdk.colormap_get_system()
    +
    +        self.fg_tags = {}
    +        self.bg_tags = {}
    +        self.font_tags = {}
    +        self.size_tags = {}
    +        self.bold_tag = self.create_tag("bold", weight=pango.WEIGHT_BOLD)
    +        self.italic_tag = self.create_tag("italic", style=pango.STYLE_ITALIC)
    +        self.underline_tag = self.create_tag("underline",
    +            underline=pango.UNDERLINE_SINGLE)
    +        self.strike_tag = self.create_tag("strike", strikethrough=True)
    +
    +    def put_text(self, text, fg_color=None, bg_color=None, font=None, size=None,
    +        bold=False, italic=False, underline=False, strike=False):
    +        '''insert text at the current position with the style defined by the
    +        optional parameters'''
    +        tags = self._parse_tags(fg_color, bg_color, font, size, bold, italic,
    +            underline, strike)
    +        iterator = self.get_iter_at_mark(self.get_insert())
    +        self._insert(iterator, text, tags)
    +
    +    def _insert(self, iterator, text, tags=None):
    +        '''insert text at the current position with the style defined by the
    +        optional parameters'''
    +        if tags is not None:
    +            self.insert_with_tags(iterator, text, *tags)
    +        else:
    +            self.insert(iterator, text)
    +
    +    def _parse_tags(self, fg_color=None, bg_color=None, font=None, size=None,
    +        bold=False, italic=False, underline=False, strike=False):
    +        '''parse the parameters and return a list of tags to apply that
    +        format
    +        '''
    +        tags = []
    +
    +        if fg_color:
    +            tag = self._parse_fg(fg_color)
    +            if tag:
    +                tags.append(tag)
    +
    +        if bg_color:
    +            tag = self._parse_bg(bg_color)
    +            if tag:
    +                tags.append(tag)
    +
    +        if font:
    +            tag = self._parse_font(font)
    +            if tag:
    +                tags.append(tag)
    +
    +        if size:
    +            tag = self._parse_size(size)
    +            if tag:
    +                tags.append(tag)
    +
    +        if bold:
    +            tags.append(self.bold_tag)
    +
    +        if italic:
    +            tags.append(self.italic_tag)
    +
    +        if underline:
    +            tags.append(self.underline_tag)
    +
    +        if strike:
    +            tags.append(self.strike_tag)
    +
    +        return tags
    +
    +    def _parse_fg(self, value):
    +        '''parse the foreground color and return a tag'''
    +        if value in self.fg_tags:
    +            return self.fg_tags[value]
    +
    +        try:
    +            color = gtk.gdk.color_parse(value)
    +            self.colormap.alloc_color(color)
    +        except ValueError:
    +            return None
    +
    +        color_tag = self.create_tag('fg_' + value[1:], foreground_gdk=color)
    +        self.fg_tags[value] = color_tag
    +
    +        return color_tag
    +
    +    def _parse_bg(self, value):
    +        '''parse the background color and return a tag'''
    +        if value in self.bg_tags:
    +            return self.bg_tags[value]
    +
    +        try:
    +            color = gtk.gdk.color_parse(value)
    +            self.colormap.alloc_color(color)
    +        except ValueError:
    +            return None
    +
    +        color_tag = self.create_tag('bg_' + value[1:], background_gdk=color)
    +        self.bg_tags[value] = color_tag
    +
    +        return color_tag
    +
    +    def _parse_font(self, value):
    +        '''parse the font and return a tag'''
    +        if value in self.font_tags:
    +            return self.font_tags[value]
    +
    +        font_tag = self.create_tag('font_' + value.replace(' ', '_'),
    +            font=value)
    +        self.font_tags[value] = font_tag
    +
    +        return font_tag
    +
    +    def _parse_size(self, value):
    +        '''parse the font size and return a tag'''
    +        if value in self.size_tags:
    +            return self.size_tags[value]
    +
    +        size_tag = self.create_tag('size_' + str(value), size_points=value)
    +        self.size_tags[value] = size_tag
    +        return size_tag
    +
    +def test():
    +    '''do some tests with the buffer'''
    +    import sys
    +    def on_close(widget, event):
    +        '''method called when the window is closed'''
    +        sys.exit(0)
    +
    +    window = gtk.Window()
    +    window.set_default_size(640, 480)
    +    window.connect('delete-event', on_close)
    +    textview = gtk.TextView()
    +    buff = RichBuffer()
    +    textview.set_buffer(buff)
    +    window.add(textview)
    +    window.show_all()
    +    buff.put_text('buenas, como va? ', '#CCCCCC', '#000000', 'Arial', 12)
    +    buff.put_text('esto es una prueba\n', '#CC0000', '#AAAAAA', 'Purisa', 14)
    +    buff.put_text('un poco de formato\n', '#00CC00', '#FFFFFF', 'Andale Mono',
    +        8, True, True, True, True)
    +    buff.put_text('un poco mas\n', '#CCCCCC', '#0000CC', 'Andale Mono', 16,
    +        False, True, False, True)
    +    gtk.main()
    +
    +if __name__ == '__main__':
    +    test()
     
    /images/Recetario/Gui/Gtk/RichText/GtkRichText.png

    Más información:

      diff --git a/recetario/gui/gtk/runner/index.html b/recetario/gui/gtk/runner/index.html index fa0373b03..8f1336415 100644 --- a/recetario/gui/gtk/runner/index.html +++ b/recetario/gui/gtk/runner/index.html @@ -28,7 +28,7 @@ callback f"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    @@ -97,176 +97,176 @@

    Gtkrunner

    func(*args, **kwargs) será llamada en un thread aparte el cuál será monitoreado periódicamente por su finalizacion. Una vez terminado llamará a callback pasándole una tupla cuyo primer elemento es True sí la función terminó con éxito y False sí la función lanzó una excepción. El segundo elemento de la tupla es el valor retornado por la función sí tuvo éxito o la excepción lanzada en caso que haya fallado.

    Obviamente en la función esa no pueden correr código relacionado con gtk.

    -
    '''example of a generic class to run a given function in a thread and call a
    -callback in the main thread with the result of the function'''
    -
    -import gtk
    -import glib
    -import time
    -import Queue
    -import urllib
    -import threading
    -
    -class GtkRunner(threading.Thread):
    -    '''run *func* in a thread with *args* and *kwargs* as arguments, when
    -    finished call callback with a two item tuple containing a boolean as first
    -    item informing if the function returned correctly and the returned value or
    -    the exception thrown as second item
    -    '''
    -
    -    def __init__(self, callback, func, *args, **kwargs):
    -        threading.Thread.__init__(self)
    -        self.setDaemon(True)
    -
    -        self.callback = callback
    -        self.func = func
    -        self.args = args
    -        self.kwargs = kwargs
    -
    -        self.result = Queue.Queue()
    -
    -        self.start()
    -        glib.timeout_add_seconds(1, self.check)
    -
    -    def run(self):
    -        '''
    -        main function of the thread, run func with args and kwargs
    -        and get the result, call callback with the (True, result)
    -
    -        if an exception is thrown call callback with (False, exception)
    -        '''
    -        try:
    -            result = (True, self.func(*self.args, **self.kwargs))
    -        except Exception, ex:
    -            result = (False, ex)
    -
    -        self.result.put(result)
    -
    -    def check(self):
    -        '''
    -        check if func finished
    -        '''
    -        try:
    -            result = self.result.get(False, 0.1)
    -        except Queue.Empty:
    -            return True
    -
    -        self.callback(result)
    -        return False
    -
    -
    -def main():
    -    '''
    -    main function called when the module is run from the command line
    -    '''
    -
    -    def return_slow(result, sleep=5):
    -        '''
    -        a demo function that returns result slowly
    -        '''
    -        time.sleep(sleep)
    -        return result
    -
    -    def fail_slow(message, sleep=5):
    -        '''
    -        a demo function that raises an exception slowly
    -        '''
    -        time.sleep(sleep)
    -        raise Exception(message)
    -
    -    def load_site(url):
    -        '''
    -        a demo function that loads the content of a url
    -        '''
    -        return urllib.urlopen(url).read()
    -
    -    class Display(gtk.Window):
    -        '''
    -        a window to display some content that loads slowly
    -        '''
    -
    -        def __init__(self, text, func, *args, **kwargs):
    -            gtk.Window.__init__(self)
    -            self.set_default_size(400, 300)
    -            self.set_title("display")
    -            self.set_border_width(2)
    -
    -            self.func = func
    -            self.args = args
    -            self.kwargs = kwargs
    -
    -            vbox = gtk.VBox(spacing=2)
    -            scroll = gtk.ScrolledWindow()
    -            self.text = gtk.TextView()
    -            self.text.get_buffer().set_text(text)
    -
    -            scroll.add(self.text)
    -
    -            vbox.pack_start(scroll, True, True)
    -
    -            self.loading = gtk.ProgressBar()
    -            self.is_loading = False
    -
    -            vbox.pack_start(self.loading, False)
    -
    -            buttons = gtk.HButtonBox()
    -            self.run = gtk.Button(stock=gtk.STOCK_EXECUTE)
    -            self.run.connect('clicked', self._on_run_clicked)
    -            buttons.pack_start(self.run)
    -
    -            vbox.pack_start(buttons, False)
    -
    -            self.add(vbox)
    -
    -            vbox.show_all()
    -            self.loading.hide()
    -            self.connect("delete-event", gtk.main_quit)
    -
    -        def _on_run_clicked(self, button):
    -            self.set_loading()
    -            GtkRunner(self._on_result_ready, self.func, *self.args,
    -                    **self.kwargs)
    -
    -        def set_loading(self, is_loading=True):
    -            '''
    -            set the window to the loading state
    -            '''
    -            self.is_loading = is_loading
    -            self.run.set_sensitive(not is_loading)
    -
    -            if is_loading:
    -                self.loading.show()
    -                glib.timeout_add(500, self._make_progress_bar_go_crazy)
    -            else:
    -                self.loading.hide()
    -
    -        def _on_result_ready(self, result):
    -            status, value = result
    -            self.set_loading(False)
    -
    -            if status:
    -                content = str(value)
    -            else:
    -                content = "exception running function: %s" % str(value)
    -
    -            self.text.get_buffer().set_text(content)
    -
    -        def _make_progress_bar_go_crazy(self):
    -            if self.is_loading:
    -                self.loading.pulse()
    -
    -            return self.is_loading
    -
    -    gtk.gdk.threads_init()
    -    Display("show text after some seconds", return_slow, "I load slowly").show()
    -    Display("raise an exception after some seconds", fail_slow,
    -            "I fail slowly").show()
    -    Display("load the content of website", load_site,
    -            "http://marianoguerra.com.ar").show()
    -    gtk.main()
    -
    -if __name__ == '__main__':
    -    main()
    +
    '''example of a generic class to run a given function in a thread and call a
    +callback in the main thread with the result of the function'''
    +
    +import gtk
    +import glib
    +import time
    +import Queue
    +import urllib
    +import threading
    +
    +class GtkRunner(threading.Thread):
    +    '''run *func* in a thread with *args* and *kwargs* as arguments, when
    +    finished call callback with a two item tuple containing a boolean as first
    +    item informing if the function returned correctly and the returned value or
    +    the exception thrown as second item
    +    '''
    +
    +    def __init__(self, callback, func, *args, **kwargs):
    +        threading.Thread.__init__(self)
    +        self.setDaemon(True)
    +
    +        self.callback = callback
    +        self.func = func
    +        self.args = args
    +        self.kwargs = kwargs
    +
    +        self.result = Queue.Queue()
    +
    +        self.start()
    +        glib.timeout_add_seconds(1, self.check)
    +
    +    def run(self):
    +        '''
    +        main function of the thread, run func with args and kwargs
    +        and get the result, call callback with the (True, result)
    +
    +        if an exception is thrown call callback with (False, exception)
    +        '''
    +        try:
    +            result = (True, self.func(*self.args, **self.kwargs))
    +        except Exception, ex:
    +            result = (False, ex)
    +
    +        self.result.put(result)
    +
    +    def check(self):
    +        '''
    +        check if func finished
    +        '''
    +        try:
    +            result = self.result.get(False, 0.1)
    +        except Queue.Empty:
    +            return True
    +
    +        self.callback(result)
    +        return False
    +
    +
    +def main():
    +    '''
    +    main function called when the module is run from the command line
    +    '''
    +
    +    def return_slow(result, sleep=5):
    +        '''
    +        a demo function that returns result slowly
    +        '''
    +        time.sleep(sleep)
    +        return result
    +
    +    def fail_slow(message, sleep=5):
    +        '''
    +        a demo function that raises an exception slowly
    +        '''
    +        time.sleep(sleep)
    +        raise Exception(message)
    +
    +    def load_site(url):
    +        '''
    +        a demo function that loads the content of a url
    +        '''
    +        return urllib.urlopen(url).read()
    +
    +    class Display(gtk.Window):
    +        '''
    +        a window to display some content that loads slowly
    +        '''
    +
    +        def __init__(self, text, func, *args, **kwargs):
    +            gtk.Window.__init__(self)
    +            self.set_default_size(400, 300)
    +            self.set_title("display")
    +            self.set_border_width(2)
    +
    +            self.func = func
    +            self.args = args
    +            self.kwargs = kwargs
    +
    +            vbox = gtk.VBox(spacing=2)
    +            scroll = gtk.ScrolledWindow()
    +            self.text = gtk.TextView()
    +            self.text.get_buffer().set_text(text)
    +
    +            scroll.add(self.text)
    +
    +            vbox.pack_start(scroll, True, True)
    +
    +            self.loading = gtk.ProgressBar()
    +            self.is_loading = False
    +
    +            vbox.pack_start(self.loading, False)
    +
    +            buttons = gtk.HButtonBox()
    +            self.run = gtk.Button(stock=gtk.STOCK_EXECUTE)
    +            self.run.connect('clicked', self._on_run_clicked)
    +            buttons.pack_start(self.run)
    +
    +            vbox.pack_start(buttons, False)
    +
    +            self.add(vbox)
    +
    +            vbox.show_all()
    +            self.loading.hide()
    +            self.connect("delete-event", gtk.main_quit)
    +
    +        def _on_run_clicked(self, button):
    +            self.set_loading()
    +            GtkRunner(self._on_result_ready, self.func, *self.args,
    +                    **self.kwargs)
    +
    +        def set_loading(self, is_loading=True):
    +            '''
    +            set the window to the loading state
    +            '''
    +            self.is_loading = is_loading
    +            self.run.set_sensitive(not is_loading)
    +
    +            if is_loading:
    +                self.loading.show()
    +                glib.timeout_add(500, self._make_progress_bar_go_crazy)
    +            else:
    +                self.loading.hide()
    +
    +        def _on_result_ready(self, result):
    +            status, value = result
    +            self.set_loading(False)
    +
    +            if status:
    +                content = str(value)
    +            else:
    +                content = "exception running function: %s" % str(value)
    +
    +            self.text.get_buffer().set_text(content)
    +
    +        def _make_progress_bar_go_crazy(self):
    +            if self.is_loading:
    +                self.loading.pulse()
    +
    +            return self.is_loading
    +
    +    gtk.gdk.threads_init()
    +    Display("show text after some seconds", return_slow, "I load slowly").show()
    +    Display("raise an exception after some seconds", fail_slow,
    +            "I fail slowly").show()
    +    Display("load the content of website", load_site,
    +            "http://marianoguerra.com.ar").show()
    +    gtk.main()
    +
    +if __name__ == '__main__':
    +    main()
     
    diff --git a/recetario/gui/gtk/statusicon/index.html b/recetario/gui/gtk/statusicon/index.html index 72b24011c..f0257e691 100644 --- a/recetario/gui/gtk/statusicon/index.html +++ b/recetario/gui/gtk/statusicon/index.html @@ -31,7 +31,7 @@ class Tr"> - +Ir al contenido principal @@ -65,12 +65,12 @@ - + @@ -91,60 +91,60 @@

    Gtkstatusicon

    Aplicación con ícono en el área de notificaciones.

    Tiene un menú contextual (About/Quit) y con el botón izquierdo abre una ventana simple.

    -/images/Recetario/Gui/Gtk/StatusIcon/trayapp.png
    '''Mini ejemplo de system tray app.'''
    -
    -import gtk
    -
    -class TrayApp:
    -
    -    def __init__(self):
    -        self.statusicon = gtk.StatusIcon()
    -        self.statusicon.set_from_stock(gtk.STOCK_INFO)
    -        self.statusicon.set_tooltip('StatusIcon Example')
    -        self.statusicon.connect('popup-menu', self.right_click_event)
    -        self.statusicon.connect('activate', self.left_click_event)
    -
    -    def left_click_event(self, status_icon):
    -        # Para que solo abra una ventana
    -        if not getattr(self, 'window', None):
    -            self.label = gtk.Label('Hola pyar')
    -            self.window = gtk.Window()
    -            self.window.set_default_size(200, 200)
    -            self.window.set_title('Hello world')
    -            self.window.connect('delete_event', self.exit_window)
    -            self.window.add(self.label)
    -            self.window.show_all()
    -
    -    def exit_window(self, widget, event, data=None):
    -        del self.window
    -
    -    def right_click_event(self, status_icon, button, activate_time):
    -        menu = gtk.Menu()
    -        about = gtk.MenuItem('About')
    -        quit = gtk.MenuItem('Quit')
    -        about.connect('activate', self.show_about_dialog)
    -        quit.connect('activate', gtk.main_quit)
    -        menu.append(about)
    -        menu.append(quit)
    -        menu.show_all()
    -        menu.popup(None, None, gtk.status_icon_position_menu,
    -                   button, activate_time, self.statusicon)
    -
    -    def show_about_dialog(self, widget):
    -                about_dialog = gtk.AboutDialog()
    -                about_dialog.set_destroy_with_parent(True)
    -                about_dialog.set_name('StatusIcon Example')
    -                about_dialog.set_version('1.0')
    -                about_dialog.set_authors(['Name Lastname'])
    -                about_dialog.run()
    -                about_dialog.destroy()
    -
    -    def main(self):
    -        gtk.main()
    -
    -if __name__ == '__main__':
    -    tray_app = TrayApp()
    -    tray_app.main()
    +/images/Recetario/Gui/Gtk/StatusIcon/trayapp.png
    '''Mini ejemplo de system tray app.'''
    +
    +import gtk
    +
    +class TrayApp:
    +
    +    def __init__(self):
    +        self.statusicon = gtk.StatusIcon()
    +        self.statusicon.set_from_stock(gtk.STOCK_INFO)
    +        self.statusicon.set_tooltip('StatusIcon Example')
    +        self.statusicon.connect('popup-menu', self.right_click_event)
    +        self.statusicon.connect('activate', self.left_click_event)
    +
    +    def left_click_event(self, status_icon):
    +        # Para que solo abra una ventana
    +        if not getattr(self, 'window', None):
    +            self.label = gtk.Label('Hola pyar')
    +            self.window = gtk.Window()
    +            self.window.set_default_size(200, 200)
    +            self.window.set_title('Hello world')
    +            self.window.connect('delete_event', self.exit_window)
    +            self.window.add(self.label)
    +            self.window.show_all()
    +
    +    def exit_window(self, widget, event, data=None):
    +        del self.window
    +
    +    def right_click_event(self, status_icon, button, activate_time):
    +        menu = gtk.Menu()
    +        about = gtk.MenuItem('About')
    +        quit = gtk.MenuItem('Quit')
    +        about.connect('activate', self.show_about_dialog)
    +        quit.connect('activate', gtk.main_quit)
    +        menu.append(about)
    +        menu.append(quit)
    +        menu.show_all()
    +        menu.popup(None, None, gtk.status_icon_position_menu,
    +                   button, activate_time, self.statusicon)
    +
    +    def show_about_dialog(self, widget):
    +                about_dialog = gtk.AboutDialog()
    +                about_dialog.set_destroy_with_parent(True)
    +                about_dialog.set_name('StatusIcon Example')
    +                about_dialog.set_version('1.0')
    +                about_dialog.set_authors(['Name Lastname'])
    +                about_dialog.run()
    +                about_dialog.destroy()
    +
    +    def main(self):
    +        gtk.main()
    +
    +if __name__ == '__main__':
    +    tray_app = TrayApp()
    +    tray_app.main()
     

    Más info en http://www.learnpygtk.org/pygtktutorial/statusicon.html

    diff --git a/recetario/gui/gtk/stockitems/index.html b/recetario/gui/gtk/stockitems/index.html index 0991e9aed..3bcfb0c2a 100644 --- a/recetario/gui/gtk/stockitems/index.html +++ b/recetario/gui/gtk/stockitems/index.html @@ -31,7 +31,7 @@ def run(): '''muestra una ventana "> - + Ir al contenido principal @@ -65,12 +65,12 @@ - +
    @@ -91,43 +91,43 @@

    Gtk Stock Items

    Ejemplo que muestra todos los íconos stock de gtk con su respectivo nombre.

    Un screenshot:

    -/images/Recetario/Gui/Gtk/StockItems/stock-gtk.png
    '''modulo que muestra el uso de los stock icons en gtk'''
    -import gtk
    -
    -def run():
    -    '''muestra una ventana con algunos elementos con stock icons'''
    -    ventana = gtk.Window()
    -    ventana.set_default_size(400, 400)
    -
    -    box = gtk.VBox(spacing=4)
    -
    -    for id in gtk.stock_list_ids():
    -        imagen = gtk.Image()
    -        imagen.set_from_stock(id, gtk.ICON_SIZE_BUTTON)
    -
    -        etiqueta = gtk.Label("gtk.STOCK" + id[3:].replace("-", "_").upper())
    -        etiqueta.set_alignment(0.0, 0.5)
    -
    -        caja = gtk.HBox()
    -
    -        caja.pack_start(imagen, False)
    -        caja.pack_start(etiqueta)
    -
    -        box.pack_start(caja)
    -
    -    scroll = gtk.ScrolledWindow()
    -    scroll.add_with_viewport(box)
    -    scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    -
    -    ventana.add(scroll)
    -
    -    ventana.connect('delete-event', gtk.main_quit)
    -    ventana.show_all()
    -    gtk.main()
    -
    -
    -if __name__ == '__main__':
    -    run()
    +/images/Recetario/Gui/Gtk/StockItems/stock-gtk.png
    '''modulo que muestra el uso de los stock icons en gtk'''
    +import gtk
    +
    +def run():
    +    '''muestra una ventana con algunos elementos con stock icons'''
    +    ventana = gtk.Window()
    +    ventana.set_default_size(400, 400)
    +
    +    box = gtk.VBox(spacing=4)
    +
    +    for id in gtk.stock_list_ids():
    +        imagen = gtk.Image()
    +        imagen.set_from_stock(id, gtk.ICON_SIZE_BUTTON)
    +
    +        etiqueta = gtk.Label("gtk.STOCK" + id[3:].replace("-", "_").upper())
    +        etiqueta.set_alignment(0.0, 0.5)
    +
    +        caja = gtk.HBox()
    +
    +        caja.pack_start(imagen, False)
    +        caja.pack_start(etiqueta)
    +
    +        box.pack_start(caja)
    +
    +    scroll = gtk.ScrolledWindow()
    +    scroll.add_with_viewport(box)
    +    scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    +
    +    ventana.add(scroll)
    +
    +    ventana.connect('delete-event', gtk.main_quit)
    +    ventana.show_all()
    +    gtk.main()
    +
    +
    +if __name__ == '__main__':
    +    run()
     
    diff --git a/recetario/gui/gtk/vbox/index.html b/recetario/gui/gtk/vbox/index.html index 9c388c351..466b3629a 100644 --- a/recetario/gui/gtk/vbox/index.html +++ b/recetario/gui/gtk/vbox/index.html @@ -32,7 +32,7 @@ "> - +Ir al contenido principal @@ -66,12 +66,12 @@ - + @@ -91,39 +91,39 @@

    Gtkvbox

    Ejemplo que muestra el uso de vbox (cajas verticales) para ordenar elementos de forma vertical

    -/images/Recetario/Gui/Gtk/VBox/vbox.png
    import gtk
    -import sys
    -
    -class Ventana(gtk.Window):
    -    '''clase que define una ventana que saluda'''
    -
    -    def __init__(self):
    -        '''constructor, se llama al constructor de la clase padre'''
    -        gtk.Window.__init__(self)
    -
    -        self.set_default_size(200, 200)
    -        self.set_title("vbox")
    -        # creamos una caja vertical que contiene elementos
    -        # de manera vertical
    -        self.vbox = gtk.VBox()
    -        # agregamos tres elementos
    -        self.vbox.pack_start(gtk.Label("uno"))
    -        self.vbox.pack_start(gtk.Label("dos"))
    -        self.vbox.pack_start(gtk.Label("tres"))
    -
    -        self.add(self.vbox)
    -        self.vbox.show_all()
    -
    -        self.connect("delete-event", self.on_delete)
    -
    -    def on_delete(self, window, event):
    -        '''llamado cuando se cierra la ventana'''
    -        sys.exit(0)
    -
    -if __name__ == "__main__":
    -    ventana = Ventana()
    -    ventana.show()
    -    gtk.main()
    +/images/Recetario/Gui/Gtk/VBox/vbox.png
    import gtk
    +import sys
    +
    +class Ventana(gtk.Window):
    +    '''clase que define una ventana que saluda'''
    +
    +    def __init__(self):
    +        '''constructor, se llama al constructor de la clase padre'''
    +        gtk.Window.__init__(self)
    +
    +        self.set_default_size(200, 200)
    +        self.set_title("vbox")
    +        # creamos una caja vertical que contiene elementos
    +        # de manera vertical
    +        self.vbox = gtk.VBox()
    +        # agregamos tres elementos
    +        self.vbox.pack_start(gtk.Label("uno"))
    +        self.vbox.pack_start(gtk.Label("dos"))
    +        self.vbox.pack_start(gtk.Label("tres"))
    +
    +        self.add(self.vbox)
    +        self.vbox.show_all()
    +
    +        self.connect("delete-event", self.on_delete)
    +
    +    def on_delete(self, window, event):
    +        '''llamado cuando se cierra la ventana'''
    +        sys.exit(0)
    +
    +if __name__ == "__main__":
    +    ventana = Ventana()
    +    ventana.show()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/webkiteditor/index.html b/recetario/gui/gtk/webkiteditor/index.html index b3a48613c..bf37d52ba 100644 --- a/recetario/gui/gtk/webkiteditor/index.html +++ b/recetario/gui/gtk/webkiteditor/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -86,67 +86,67 @@

    Gtk Webkit Editor

    Ejemplo de cómo usar webkit para editar páginas HTML como si fuera un editor.

    Para probarlo correlo, entra una dirección que empiece con http://, hace foco en alguna parte de la página y ponete a tipear como si fuera un editor de texto común.

    Un ejemplo de su uso (tarea del autor encontrar los cambios 😉).

    -/images/Recetario/Gui/Gtk/WebkitEditor/webkit.png
    import gtk
    -import webkit
    -
    -class Editor(webkit.WebView):
    -    '''a webkit editor'''
    -
    -    def __init__(self):
    -        webkit.WebView.__init__(self)
    -        self.set_editable(True)
    -
    -class EditorWindow(gtk.Window):
    -    '''the editor window'''
    -
    -    def __init__(self):
    -        gtk.Window.__init__(self)
    -        self.set_title("webkit editor")
    -        self.set_default_size(800, 600)
    -
    -        self.entry = gtk.Entry()
    -        self.entry.set_text("http://webkit.org")
    -        self.entry.connect('activate', self._on_entry_activate)
    -        self.editor = Editor()
    -        scroll = gtk.ScrolledWindow()
    -        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    -        scroll.set_shadow_type(gtk.SHADOW_IN)
    -
    -        scroll.add(self.editor)
    -
    -        vbox = gtk.VBox()
    -        vbox.pack_start(self.entry, False)
    -        vbox.pack_start(scroll)
    -
    -        self.add(vbox)
    -        vbox.show_all()
    -
    -    def load(self, url):
    -        '''load the given url in the editor and set it to editable'''
    -        self.editor.open(url)
    -
    -    def _on_entry_activate(self, entry):
    -        '''callback called when the user hits enter on the entry'''
    -        self.load(entry.get_text())
    -
    -if __name__ == '__main__':
    -    window = EditorWindow()
    -    window.show()
    -    window.entry.activate()
    -    gtk.main()
    +/images/Recetario/Gui/Gtk/WebkitEditor/webkit.png
    import gtk
    +import webkit
    +
    +class Editor(webkit.WebView):
    +    '''a webkit editor'''
    +
    +    def __init__(self):
    +        webkit.WebView.__init__(self)
    +        self.set_editable(True)
    +
    +class EditorWindow(gtk.Window):
    +    '''the editor window'''
    +
    +    def __init__(self):
    +        gtk.Window.__init__(self)
    +        self.set_title("webkit editor")
    +        self.set_default_size(800, 600)
    +
    +        self.entry = gtk.Entry()
    +        self.entry.set_text("http://webkit.org")
    +        self.entry.connect('activate', self._on_entry_activate)
    +        self.editor = Editor()
    +        scroll = gtk.ScrolledWindow()
    +        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    +        scroll.set_shadow_type(gtk.SHADOW_IN)
    +
    +        scroll.add(self.editor)
    +
    +        vbox = gtk.VBox()
    +        vbox.pack_start(self.entry, False)
    +        vbox.pack_start(scroll)
    +
    +        self.add(vbox)
    +        vbox.show_all()
    +
    +    def load(self, url):
    +        '''load the given url in the editor and set it to editable'''
    +        self.editor.open(url)
    +
    +    def _on_entry_activate(self, entry):
    +        '''callback called when the user hits enter on the entry'''
    +        self.load(entry.get_text())
    +
    +if __name__ == '__main__':
    +    window = EditorWindow()
    +    window.show()
    +    window.entry.activate()
    +    gtk.main()
     

    Tengan en cuenta que en Ubuntu inferior 10.04 python-webkit en gtk nececita SI o SI llamar a "gtk.gdk.threads_init()", sino tira error:

    -
    GLib-ERROR **: The thread system is not yet initialized.
    -aborting...
    -Cancelado
    +
    GLib-ERROR **: The thread system is not yet initialized.
    +aborting...
    +Cancelado
     

    Entonces deberán agregar un "gtk.gdk.threads_init()" antes de llamar a "EditorWindow_()". El final del código les quedará de la siguiente manera:

    -
    if __name__ == '__main__':
    -    gtk.gdk.threads_init()
    -    window = EditorWindow()
    -    window.show()
    -    window.entry.activate()
    -    gtk.main()
    +
    if __name__ == '__main__':
    +    gtk.gdk.threads_init()
    +    window = EditorWindow()
    +    window.show()
    +    window.entry.activate()
    +    gtk.main()
     
    diff --git a/recetario/gui/gtk/xmlrpcserver/index.html b/recetario/gui/gtk/xmlrpcserver/index.html index 0fc48ab5f..e37107701 100644 --- a/recetario/gui/gtk/xmlrpcserver/index.html +++ b/recetario/gui/gtk/xmlrpcserver/index.html @@ -32,7 +32,7 @@ dialog = gtk.Dialog("Hello dialog", '> - + Ir al contenido principal @@ -66,12 +66,12 @@ - +
    @@ -91,46 +91,46 @@

    Xmlrpcserver

    Servidor XMLRPC dentro de un hilo gtk

    -
    from SimpleXMLRPCServer import SimpleXMLRPCServer
    -import gtk
    -import gobject
    -import time
    -
    -def hello(name):
    -        dialog = gtk.Dialog("Hello dialog",
    -                        None,
    -                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
    -                        (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
    -                                gtk.STOCK_OK, gtk.RESPONSE_ACCEPT,)
    -                        )
    -        label = gtk.Label('Hello %s'%name)
    -        dialog.vbox.pack_start(label)
    -        label.show()
    -        response = dialog.run()
    -        dialog.destroy()
    -        return response
    -def change_time(label):
    -        label.set_text(repr(time.time()))
    -        return True
    -def handle_request(source, condition, webservice):
    -        try:
    -                webservice.handle_request()
    -        except:
    -                pass
    -        return True
    -
    -s = SimpleXMLRPCServer(('localhost',8080))
    -s.register_function(hello)
    -gobject.io_add_watch(s.socket, gobject.IO_IN,
    -                     handle_request, s)
    -win = gtk.Window()
    -win.connect('destroy', gtk.main_quit)
    -win.set_size_request(300,300)
    -label = gtk.Label('Main window')
    -gobject.timeout_add(100, change_time, label)
    -win.add(label)
    -win.show_all()
    -gtk.main()
    +
    from SimpleXMLRPCServer import SimpleXMLRPCServer
    +import gtk
    +import gobject
    +import time
    +
    +def hello(name):
    +        dialog = gtk.Dialog("Hello dialog",
    +                        None,
    +                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
    +                        (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
    +                                gtk.STOCK_OK, gtk.RESPONSE_ACCEPT,)
    +                        )
    +        label = gtk.Label('Hello %s'%name)
    +        dialog.vbox.pack_start(label)
    +        label.show()
    +        response = dialog.run()
    +        dialog.destroy()
    +        return response
    +def change_time(label):
    +        label.set_text(repr(time.time()))
    +        return True
    +def handle_request(source, condition, webservice):
    +        try:
    +                webservice.handle_request()
    +        except:
    +                pass
    +        return True
    +
    +s = SimpleXMLRPCServer(('localhost',8080))
    +s.register_function(hello)
    +gobject.io_add_watch(s.socket, gobject.IO_IN,
    +                     handle_request, s)
    +win = gtk.Window()
    +win.connect('destroy', gtk.main_quit)
    +win.set_size_request(300,300)
    +label = gtk.Label('Main window')
    +gobject.timeout_add(100, change_time, label)
    +win.add(label)
    +win.show_all()
    +gtk.main()
     
    diff --git a/recetario/histograma/index.html b/recetario/histograma/index.html index 5260fcba8..722a1e26a 100644 --- a/recetario/histograma/index.html +++ b/recetario/histograma/index.html @@ -30,7 +30,7 @@ >>> from matplotlib.pylab impo"> - +Ir al contenido principal @@ -64,12 +64,12 @@ - + @@ -94,36 +94,36 @@

    Cómo Generar Un Histograma

  • Matplotlib

  • Documentación de hist

  • -
    >>> from matplotlib.pylab import hist, show
    ->>> plata = []
    ->>> a = plata.extend
    ->>> a([50])
    ->>> a([20]*10)
    ->>> a([10]*13)
    ->>> a([5]*8)
    ->>> a([2]*35)
    ->>> a([1]*1)
    ->>> plata
    -[50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 10, 10, 10, 10, 10, 10, 10,5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    ->>> hist(plata, 100, (0,100))
    -(array([ 0,  1, 35,  0,  0, 15,  0,  0,  0,  0, 25,  0,  0,  0,  0,  0,  0,
    -        0,  0,  0, 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    -        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,
    -        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    -        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    -        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0]), array([   0.,
    -          9.,   10.,   11.,   12.,   13.,   14.,   15.,   16.,   17.,
    -         18.,   19.,   20.,   21.,   22.,   23.,   24.,   25.,   26.,
    -         27.,   28.,   29.,   30.,   31.,   32.,   33.,   34.,   35.,
    -         36.,   37.,   38.,   39.,   40.,   41.,   42.,   43.,   44.,
    -         45.,   46.,   47.,   48.,   49.,   50.,   51.,   52.,   53.,
    -         54.,   55.,   56.,   57.,   58.,   59.,   60.,   61.,   62.,
    -         63.,   64.,   65.,   66.,   67.,   68.,   69.,   70.,   71.,
    -         72.,   73.,   74.,   75.,   76.,   77.,   78.,   79.,   80.,
    -         81.,   82.,   83.,   84.,   85.,   86.,   87.,   88.,   89.,
    -         90.,   91.,   92.,   93.,   94.,   95.,   96.,   97.,   98.,
    -         99.,  100.]), <a list of 100 Patch objects>)
    ->>> show()
    +
    >>> from matplotlib.pylab import hist, show
    +>>> plata = []
    +>>> a = plata.extend
    +>>> a([50])
    +>>> a([20]*10)
    +>>> a([10]*13)
    +>>> a([5]*8)
    +>>> a([2]*35)
    +>>> a([1]*1)
    +>>> plata
    +[50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 10, 10, 10, 10, 10, 10, 10,5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    +>>> hist(plata, 100, (0,100))
    +(array([ 0,  1, 35,  0,  0, 15,  0,  0,  0,  0, 25,  0,  0,  0,  0,  0,  0,
    +        0,  0,  0, 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    +        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,
    +        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    +        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    +        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0]), array([   0.,
    +          9.,   10.,   11.,   12.,   13.,   14.,   15.,   16.,   17.,
    +         18.,   19.,   20.,   21.,   22.,   23.,   24.,   25.,   26.,
    +         27.,   28.,   29.,   30.,   31.,   32.,   33.,   34.,   35.,
    +         36.,   37.,   38.,   39.,   40.,   41.,   42.,   43.,   44.,
    +         45.,   46.,   47.,   48.,   49.,   50.,   51.,   52.,   53.,
    +         54.,   55.,   56.,   57.,   58.,   59.,   60.,   61.,   62.,
    +         63.,   64.,   65.,   66.,   67.,   68.,   69.,   70.,   71.,
    +         72.,   73.,   74.,   75.,   76.,   77.,   78.,   79.,   80.,
    +         81.,   82.,   83.,   84.,   85.,   86.,   87.,   88.,   89.,
    +         90.,   91.,   92.,   93.,   94.,   95.,   96.,   97.,   98.,
    +         99.,  100.]), <a list of 100 Patch objects>)
    +>>> show()
     
    /images/Recetario/Histograma/ej_tribu.jpg
    diff --git a/recetario/index.html b/recetario/index.html index 3b47a46f0..d7749d3fb 100644 --- a/recetario/index.html +++ b/recetario/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/recetario/interceptarprints/index.html b/recetario/interceptarprints/index.html index f501059a1..dbebcd0d5 100644 --- a/recetario/interceptarprints/index.html +++ b/recetario/interceptarprints/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + @@ -83,22 +83,22 @@

    Interceptar Prints

    Esto sirve para modificar los strings que se vayan a imprimir, por ejemplo para agregarles un timestamp o algo similar. En este ejemplo lo usamos para redefinir "2" y "4". Probado en Python 2 y Python 3.

    -
    import sys
    -
    -class FakeStdout:
    -    def write(self, s):
    -        s = s.replace("2", "3")
    -        s = s.replace("4", "6")
    -        real_stdout.write(s)
    -    def flush(self):
    -        real_stdout.flush()
    -
    -real_stdout = sys.stdout
    -sys.stdout = FakeStdout()
    -
    -
    -print(2)
    -print(2 + 2)
    +
    import sys
    +
    +class FakeStdout:
    +    def write(self, s):
    +        s = s.replace("2", "3")
    +        s = s.replace("4", "6")
    +        real_stdout.write(s)
    +    def flush(self):
    +        real_stdout.flush()
    +
    +real_stdout = sys.stdout
    +sys.stdout = FakeStdout()
    +
    +
    +print(2)
    +print(2 + 2)
     
    diff --git a/recetario/ippublica/index.html b/recetario/ippublica/index.html index ec7dea68c..8d272e36e 100644 --- a/recetario/ippublica/index.html +++ b/recetario/ippublica/index.html @@ -30,7 +30,7 @@ import urllib ip = u"> - +Ir al contenido principal @@ -64,12 +64,12 @@ - + @@ -92,15 +92,15 @@

    Obtener Ip Publica

  • Cómo obtener la IP Pública, usando Python, ejemplo simple.

  • Nota: Que tengas dirección IP pública no implica que tengas conectividad.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -import urllib
    -ip = urllib.urlopen('http://automation.whatismyip.com/n09230945.asp').read() # esta URL puede ser reemplazada con otra que preste similar servicio
    -print ip
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +import urllib
    +ip = urllib.urlopen('http://automation.whatismyip.com/n09230945.asp').read() # esta URL puede ser reemplazada con otra que preste similar servicio
    +print ip
     

    Ejemplo:

    -
    sudo /usr/bin/env python getip.py
    -190.139.27.XXX
    +
    sudo /usr/bin/env python getip.py
    +190.139.27.XXX
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    Fe de Erratas: seguramente hay una forma mejor de hacerlo, pero esta funciona correctamente.

    diff --git a/recetario/iterarsobrepares/index.html b/recetario/iterarsobrepares/index.html index bb85f759c..044c24c8b 100644 --- a/recetario/iterarsobrepares/index.html +++ b/recetario/iterarsobrepares/index.html @@ -32,7 +32,7 @@ (3, 4) (5"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - +
    @@ -91,14 +91,14 @@

    Iterar Sobre Pares

    ¿Cómo iterar por ejemplo la secuencia [1,2,3,4,5,6] para que cada item sea: (1,2), (3,4), (5,6)?

    -
    >>> seq = [1,2,3,4,5,6,7]
    ->>> i = iter(seq)
    ->>> for x in zip(i,i):
    -...     print x
    -...
    -(1, 2)
    -(3, 4)
    -(5, 6)
    +
    >>> seq = [1,2,3,4,5,6,7]
    +>>> i = iter(seq)
    +>>> for x in zip(i,i):
    +...     print x
    +...
    +(1, 2)
    +(3, 4)
    +(5, 6)
     
    diff --git a/recetario/keyboardledsdemo/index.html b/recetario/keyboardledsdemo/index.html index 52aee7b1e..cf0c10048 100644 --- a/recetario/keyboardledsdemo/index.html +++ b/recetario/keyboardledsdemo/index.html @@ -26,7 +26,7 @@ Nota: Si tu teclado es a Baterías (Bluetooth, Wireless), el uso intensivo de este Scri"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + @@ -88,31 +88,31 @@

    Keyboard Leds Demo

  • Cómo controlar los 3 Leds del Teclado usando Python, ejemplo simple. Requiere Privilegios elevados en el equipo.

  • Nota: Si tu teclado es a Baterías (Bluetooth, Wireless), el uso intensivo de este Script reducirá la duracion de las mismas.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -import fcntl
    -import os
    -import time
    -
    -KDSETLED = 0x4B32
    -SCR_LED  = 0x01
    -NUM_LED  = 0x02
    -CAP_LED  = 0x04
    -
    -console_fd = os.open('/dev/console', os.O_NOCTTY)
    -
    -all_on = SCR_LED | NUM_LED | CAP_LED
    -all_off = 0
    -
    -while 1:
    -    fcntl.ioctl(console_fd, KDSETLED, all_on)
    -    time.sleep(0.1) # Aca se cambia el tiempo, o podria realizar una funcion mas compleja
    -    fcntl.ioctl(console_fd, KDSETLED, all_off)
    -    time.sleep(0.1) # Here changes the Timming, or something more complex
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +import fcntl
    +import os
    +import time
    +
    +KDSETLED = 0x4B32
    +SCR_LED  = 0x01
    +NUM_LED  = 0x02
    +CAP_LED  = 0x04
    +
    +console_fd = os.open('/dev/console', os.O_NOCTTY)
    +
    +all_on = SCR_LED | NUM_LED | CAP_LED
    +all_off = 0
    +
    +while 1:
    +    fcntl.ioctl(console_fd, KDSETLED, all_on)
    +    time.sleep(0.1) # Aca se cambia el tiempo, o podria realizar una funcion mas compleja
    +    fcntl.ioctl(console_fd, KDSETLED, all_off)
    +    time.sleep(0.1) # Here changes the Timming, or something more complex
     

    Ejemplo:

    -
    sudo /usr/bin/env python keyboardleds.py
    +
    sudo /usr/bin/env python keyboardleds.py
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    diff --git a/recetario/listarprocesos/index.html b/recetario/listarprocesos/index.html index 31bb1d296..5f1e3addd 100644 --- a/recetario/listarprocesos/index.html +++ b/recetario/listarprocesos/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +
    @@ -86,23 +86,23 @@

    Listar Procesos

    Esta receta muestra una forma de listar procesos en Python que soporta múltiples sistemas operativos

    En el ejemplo se muestra cómo listar información sobre los procesos corriendo bajo el usuario "root"

    Hace falta instalar la libreria psutil, disponible en aqui. Hay paquetes para Debian y Ubuntu, python-psutil.

    -
    import psutil
    -
    -for pid in psutil.get_pid_list():
    -    proc = psutil.Process(pid)
    -
    -    if proc.username != "root":
    -        continue
    -
    -    print proc.name, proc.cmdline, proc.pid
    +
    import psutil
    +
    +for pid in psutil.get_pid_list():
    +    proc = psutil.Process(pid)
    +
    +    if proc.username != "root":
    +        continue
    +
    +    print proc.name, proc.cmdline, proc.pid
     

    En la versión 0.3 de psutil el Ejemplo puede quedar como:

    -
    import psutil
    -
    -for proc in psutil.get_process_list():
    -    if proc.username != "root":
    -        continue
    -    print proc.name, proc.cmdline, proc.pid
    +
    import psutil
    +
    +for proc in psutil.get_process_list():
    +    if proc.username != "root":
    +        continue
    +    print proc.name, proc.cmdline, proc.pid
     
    diff --git a/recetario/localsdeunafuncionquelanzounaexcepcion/index.html b/recetario/localsdeunafuncionquelanzounaexcepcion/index.html index 10ce2a460..505a85340 100644 --- a/recetario/localsdeunafuncionquelanzounaexcepcion/index.html +++ b/recetario/localsdeunafuncionquelanzounaexcepcion/index.html @@ -26,7 +26,7 @@ En realidad son los locals de la funcion llamada. Lo uso para pasarle los locals de la funcion a un template de djan"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -87,19 +87,19 @@

    Locals De Una Funcion Que Lanzo Una Excepcion

    Ejemplo de cómo obtener las variables locales a la función que lanzo una exception.

    En realidad son los locals de la funcion llamada.

    Lo uso para pasarle los locals de la funcion a un template de django desde un decorador.

    -
    import inspect
    -
    -def fun():
    -    a, b = 1, "dos"
    -
    -    raise Exception("hi!")
    -
    -try:
    -    fun()
    -except Exception, error:
    -    fun_frame = inspect.trace()[1][0]
    -    print "locals in fun: ", fun_frame.f_locals
    -    del fun_frame
    +
    import inspect
    +
    +def fun():
    +    a, b = 1, "dos"
    +
    +    raise Exception("hi!")
    +
    +try:
    +    fun()
    +except Exception, error:
    +    fun_frame = inspect.trace()[1][0]
    +    print "locals in fun: ", fun_frame.f_locals
    +    del fun_frame
     
    diff --git a/recetario/mapeandomemoria/index.html b/recetario/mapeandomemoria/index.html index 1e12330fc..bf6f192b6 100644 --- a/recetario/mapeandomemoria/index.html +++ b/recetario/mapeandomemoria/index.html @@ -25,7 +25,7 @@ - +Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -89,174 +89,174 @@

    Mapeando Memoria

    Finalmente, memmap tiene el mapa de la memoria, y el detalle por si se quiere generar mapas más detallados o con diferente visualización.

    Probablemente para un uso concreto sea necesario extender memmap antes del memmap.sort(), agregando buffers específicos de la aplicación que no caigan dentro de lo consumido por python. Por ejemplo, los objetos mmap tienen asociados grandes pedazos de memoria que no aparecerían en el mapa, y si se usan mucho en la aplicación convendría incluirlos, o buffers significativos utilizados por bibliotecas de extensión.

    Este código sólo funciona en CPython, puesto que utiliza el hecho de que id() devuelve la dirección en memoria de un objeto. Eso no es cierto en Jython, PyPy y muchas otras implementaciones.

    -
    import cPickle
    -from guppy import hpy as heapy
    -_heapy = heapy()
    -
    -def report_memmap(mm):
    -    import re
    -    from bisect import bisect_left, bisect_right
    -
    -    mxsz = max( s for a,s in mm )
    -
    -    def usage(mn,mx,mxsz):
    -        rv = ' '
    -        for a,s in mm[bisect_left(mm,(mn-mxsz-16,0)):bisect_right(mm,(mx+1,0))]:
    -            if mn>=mx:
    -                break
    -            s += a + 16 # add 16 bytes for malloc headers
    -            if s<=mn:
    -                continue
    -            if a<mx:
    -                rv = '-' # touched the range, at least fragmented
    -            if a>mn:
    -                # cannot be fully used
    -                break
    -            #used up to s
    -            mn=s
    -        if mx <= mn:
    -            rv = '*' # used in full
    -        return rv
    -
    -    def bytes(x):
    -        if x < 1024:
    -            return '%db' % x
    -        elif x < 1024*1024:
    -            return '%.2fKb' % (x/1024.0)
    -        elif x < 1024*1024*1024:
    -            return '%.2fMb' % (x/1024.0/1024.0)
    -        else:
    -            return '%.2fGb' % (x/1024.0/1024.0/1024.0)
    -
    -    def secsize(x):
    -        rv = 4096
    -        while (x/rv/80) > 40:
    -            rv *= 2
    -        return rv
    -
    -    def report(mn,mx,ss):
    -        smxsz = max( s for a,s in mm[bisect_left(mm,(mn-mxsz-16,0)):bisect_right(mm,(mx+1,0))] )
    -        mp  = ''.join([ usage(i,i+ss,smxsz) for i in range(mn,mx,ss) ])
    -        rv  = '%s total, %s per sector\n' % (bytes(mx-mn), bytes(ss))
    -        rv += lre.sub('\\1\n',mp)
    -        rv += """
    -        Fragmentation: %.2f%%
    -        Fragmented sectors: %d
    -        Contiguous used sectors: %d
    -        Contiguous free sectors: %d
    -        """ % ( mp.count('-')*100.0/len(mp),
    -                mp.count('-'),
    -                mp.count('*'),
    -                mp.count(' ') )
    -        return rv
    -
    -    def domap(filterfn):
    -        if not any(filterfn(a) for a,s in mm):
    -            return 'empty'
    -        mn = min( a for a,s in mm if filterfn(a) )
    -        mx = max( a for a,s in mm if filterfn(a) )
    -        ss = secsize(mx-mn)
    -        mn = mn/ss*ss
    -        mx = mx/ss*ss+ss
    -        return report(mn,mx,ss)
    -
    -    lre = re.compile('(.{80,80})')
    -
    -    lomap = domap(lambda a: a <  0x80000000)
    -    medmap= domap(lambda a: a >= 0x80000000 and a < 0x100000000L)
    -    himap = domap(lambda a: a >= 0x100000000L)
    -
    -    return lomap, medmap, himap
    -
    -
    -def heapStats():
    -    global _debug_heap
    -    global _heapy
    -
    -    import StringIO
    -
    -    statdump = StringIO.StringIO()
    -    heap = _heapy.heap()
    -
    -    try:
    -        heap.dump(statdump)
    -    except:
    -        # ignore exceptions dumping... shit happens
    -        pass
    -
    -    statdumpu = StringIO.StringIO()
    -    heapu = _heapy.heapu()
    -
    -    try:
    -        heapu.dump(statdumpu)
    -    except:
    -        # ignore exceptions dumping... shit happens
    -        pass
    -
    -    statdumpbr = StringIO.StringIO()
    -    heapbr = heap.byrcs
    -
    -    try:
    -        heapbr.dump(statdumpbr)
    -    except:
    -        # ignore exceptions dumping... shit happens
    -        pass
    -
    -    refs = None
    -    try:
    -        refs = heap.stat
    -        refs.rows = list(refs.get_rows())
    -        refs.rows.sort(lambda x,y:-cmp(x.count,y.count))
    -
    -        oc = _heapy.Size.classifier.get_cli().classify
    -        id_ = id
    -        str_ = str
    -        memmap = [ (id_(x),oc(x)) for x in heap.nodes ]
    -    except:
    -        # At least the rest will be useful
    -        memmap = []
    -
    -    memmap.sort()
    -
    -    # Generate lowres reports from the memmap in four areas, lo, med, hi and very hi.
    -    # memory (memory allocations tend to group themselves in those ranges,
    -    # one is probably memmapped heap, the other is simple allocations and
    -    # the medium one must be the stack). The very high area is the mmap'd area,
    -    # where most big arrays end up.
    -    lomap, medmap, himap = report_memmap(memmap)
    -
    -    # Pickle the memmap, xmlrpclib doesn't like big integers
    -    memmap = cPickle.dumps(memmap)
    -
    -    def srepr(x):
    -        try:
    -            return repr(x)
    -        except Exception,e:
    -            return 'ERROR: %s' (e,)
    -
    -    rv = dict(
    -        byclodo = dict(
    -            reachable = map(srepr, [ heap, heap.more, heap.more.more ]),
    -            uncollectable = map(srepr, [ heapu, heapu.more, heapu.more.more ]),
    -            statdump = statdump.getvalue(),
    -            statdumpu = statdumpu.getvalue(),
    -            refs = srepr(refs)
    -        ),
    -        byrcs = dict(
    -            reachable = map(srepr, [ heapbr, heapbr.more, heapbr.more.more ]),
    -            statdump = statdumpbr.getvalue()
    -        ),
    -        memmap = dict(
    -            detail = memmap,
    -            lo = lomap,
    -            med = medmap,
    -            hi = himap
    -        )
    -    )
    -
    -    # return a pickle dump, not by pure xmlrpc
    -    #   (xmlrpc is picky, doesn't support big ints)
    -    return cPickle.dumps(rv, 2)
    +
    import cPickle
    +from guppy import hpy as heapy
    +_heapy = heapy()
    +
    +def report_memmap(mm):
    +    import re
    +    from bisect import bisect_left, bisect_right
    +
    +    mxsz = max( s for a,s in mm )
    +
    +    def usage(mn,mx,mxsz):
    +        rv = ' '
    +        for a,s in mm[bisect_left(mm,(mn-mxsz-16,0)):bisect_right(mm,(mx+1,0))]:
    +            if mn>=mx:
    +                break
    +            s += a + 16 # add 16 bytes for malloc headers
    +            if s<=mn:
    +                continue
    +            if a<mx:
    +                rv = '-' # touched the range, at least fragmented
    +            if a>mn:
    +                # cannot be fully used
    +                break
    +            #used up to s
    +            mn=s
    +        if mx <= mn:
    +            rv = '*' # used in full
    +        return rv
    +
    +    def bytes(x):
    +        if x < 1024:
    +            return '%db' % x
    +        elif x < 1024*1024:
    +            return '%.2fKb' % (x/1024.0)
    +        elif x < 1024*1024*1024:
    +            return '%.2fMb' % (x/1024.0/1024.0)
    +        else:
    +            return '%.2fGb' % (x/1024.0/1024.0/1024.0)
    +
    +    def secsize(x):
    +        rv = 4096
    +        while (x/rv/80) > 40:
    +            rv *= 2
    +        return rv
    +
    +    def report(mn,mx,ss):
    +        smxsz = max( s for a,s in mm[bisect_left(mm,(mn-mxsz-16,0)):bisect_right(mm,(mx+1,0))] )
    +        mp  = ''.join([ usage(i,i+ss,smxsz) for i in range(mn,mx,ss) ])
    +        rv  = '%s total, %s per sector\n' % (bytes(mx-mn), bytes(ss))
    +        rv += lre.sub('\\1\n',mp)
    +        rv += """
    +        Fragmentation: %.2f%%
    +        Fragmented sectors: %d
    +        Contiguous used sectors: %d
    +        Contiguous free sectors: %d
    +        """ % ( mp.count('-')*100.0/len(mp),
    +                mp.count('-'),
    +                mp.count('*'),
    +                mp.count(' ') )
    +        return rv
    +
    +    def domap(filterfn):
    +        if not any(filterfn(a) for a,s in mm):
    +            return 'empty'
    +        mn = min( a for a,s in mm if filterfn(a) )
    +        mx = max( a for a,s in mm if filterfn(a) )
    +        ss = secsize(mx-mn)
    +        mn = mn/ss*ss
    +        mx = mx/ss*ss+ss
    +        return report(mn,mx,ss)
    +
    +    lre = re.compile('(.{80,80})')
    +
    +    lomap = domap(lambda a: a <  0x80000000)
    +    medmap= domap(lambda a: a >= 0x80000000 and a < 0x100000000L)
    +    himap = domap(lambda a: a >= 0x100000000L)
    +
    +    return lomap, medmap, himap
    +
    +
    +def heapStats():
    +    global _debug_heap
    +    global _heapy
    +
    +    import StringIO
    +
    +    statdump = StringIO.StringIO()
    +    heap = _heapy.heap()
    +
    +    try:
    +        heap.dump(statdump)
    +    except:
    +        # ignore exceptions dumping... shit happens
    +        pass
    +
    +    statdumpu = StringIO.StringIO()
    +    heapu = _heapy.heapu()
    +
    +    try:
    +        heapu.dump(statdumpu)
    +    except:
    +        # ignore exceptions dumping... shit happens
    +        pass
    +
    +    statdumpbr = StringIO.StringIO()
    +    heapbr = heap.byrcs
    +
    +    try:
    +        heapbr.dump(statdumpbr)
    +    except:
    +        # ignore exceptions dumping... shit happens
    +        pass
    +
    +    refs = None
    +    try:
    +        refs = heap.stat
    +        refs.rows = list(refs.get_rows())
    +        refs.rows.sort(lambda x,y:-cmp(x.count,y.count))
    +
    +        oc = _heapy.Size.classifier.get_cli().classify
    +        id_ = id
    +        str_ = str
    +        memmap = [ (id_(x),oc(x)) for x in heap.nodes ]
    +    except:
    +        # At least the rest will be useful
    +        memmap = []
    +
    +    memmap.sort()
    +
    +    # Generate lowres reports from the memmap in four areas, lo, med, hi and very hi.
    +    # memory (memory allocations tend to group themselves in those ranges,
    +    # one is probably memmapped heap, the other is simple allocations and
    +    # the medium one must be the stack). The very high area is the mmap'd area,
    +    # where most big arrays end up.
    +    lomap, medmap, himap = report_memmap(memmap)
    +
    +    # Pickle the memmap, xmlrpclib doesn't like big integers
    +    memmap = cPickle.dumps(memmap)
    +
    +    def srepr(x):
    +        try:
    +            return repr(x)
    +        except Exception,e:
    +            return 'ERROR: %s' (e,)
    +
    +    rv = dict(
    +        byclodo = dict(
    +            reachable = map(srepr, [ heap, heap.more, heap.more.more ]),
    +            uncollectable = map(srepr, [ heapu, heapu.more, heapu.more.more ]),
    +            statdump = statdump.getvalue(),
    +            statdumpu = statdumpu.getvalue(),
    +            refs = srepr(refs)
    +        ),
    +        byrcs = dict(
    +            reachable = map(srepr, [ heapbr, heapbr.more, heapbr.more.more ]),
    +            statdump = statdumpbr.getvalue()
    +        ),
    +        memmap = dict(
    +            detail = memmap,
    +            lo = lomap,
    +            med = medmap,
    +            hi = himap
    +        )
    +    )
    +
    +    # return a pickle dump, not by pure xmlrpc
    +    #   (xmlrpc is picky, doesn't support big ints)
    +    return cPickle.dumps(rv, 2)
     
    diff --git a/recetario/matrixpythontoy/index.html b/recetario/matrixpythontoy/index.html index 94df00b9f..33f46b00f 100644 --- a/recetario/matrixpythontoy/index.html +++ b/recetario/matrixpythontoy/index.html @@ -29,7 +29,7 @@ def __new__(cls, text, speed): self = sup'> - +Ir al contenido principal @@ -63,12 +63,12 @@ - + @@ -88,67 +88,67 @@

    Matrix Python Toy

    Efecto "The Matrix" en línea de comandos, con modificación es útil de Screen Saver o Screen Lock

    -
    import os, time, random, sys
    -
    -class message(str):
    -    def __new__(cls, text, speed):
    -        self = super(message, cls).__new__(cls, text)
    -        self.speed = speed
    -        self.y = -1*len(text)
    -        self.x = random.randint(0, display().width)
    -        self.skip = 0
    -        return self
    -
    -    def move(self):
    -        if self.speed > self.skip:
    -            self.skip += 1
    -        else:
    -            self.skip = 0
    -            self.y += 1
    -
    -class display(list):
    -    def __init__(self):
    -        self.height, self.width = [int(x) for x in os.popen('stty size', 'r').read().split()]
    -        self[:] = [' ' for y in xrange(self.height) for x in xrange(self.width)]
    -
    -    def set_vertical(self, x, y, string):
    -        string = string[::-1]
    -        if x < 0:
    -            x = 80 + x
    -        if x >= self.width:
    -            x = self.width-1
    -        if y < 0:
    -            string = string[abs(y):]
    -            y = 0
    -        if y + len(string) > self.height:
    -            string = string[0:self.height - y]
    -        if y >= self.height:
    -            return
    -        start = y*self.width+x
    -        length = self.width*(y+len(string))
    -        step = self.width
    -
    -        self[start:length:step] = string
    -
    -    def __str__(self):
    -        return ''.join(self)
    -
    -i_message = raw_input("Input a message: ")
    -messages = [message(i_message, random.randint(1, 5))]
    -for t in xrange(1000):
    -    messages.append(message(i_message, random.randint(1, 5)))
    -    d = display()
    -    for text in messages:
    -        d.set_vertical(text.x, text.y, text)
    -        text.move()
    -    sys.stdout.write(str(d))
    -    sys.stdout.flush()
    -    del d
    -    time.sleep(0.1)
    +
    import os, time, random, sys
    +
    +class message(str):
    +    def __new__(cls, text, speed):
    +        self = super(message, cls).__new__(cls, text)
    +        self.speed = speed
    +        self.y = -1*len(text)
    +        self.x = random.randint(0, display().width)
    +        self.skip = 0
    +        return self
    +
    +    def move(self):
    +        if self.speed > self.skip:
    +            self.skip += 1
    +        else:
    +            self.skip = 0
    +            self.y += 1
    +
    +class display(list):
    +    def __init__(self):
    +        self.height, self.width = [int(x) for x in os.popen('stty size', 'r').read().split()]
    +        self[:] = [' ' for y in xrange(self.height) for x in xrange(self.width)]
    +
    +    def set_vertical(self, x, y, string):
    +        string = string[::-1]
    +        if x < 0:
    +            x = 80 + x
    +        if x >= self.width:
    +            x = self.width-1
    +        if y < 0:
    +            string = string[abs(y):]
    +            y = 0
    +        if y + len(string) > self.height:
    +            string = string[0:self.height - y]
    +        if y >= self.height:
    +            return
    +        start = y*self.width+x
    +        length = self.width*(y+len(string))
    +        step = self.width
    +
    +        self[start:length:step] = string
    +
    +    def __str__(self):
    +        return ''.join(self)
    +
    +i_message = raw_input("Input a message: ")
    +messages = [message(i_message, random.randint(1, 5))]
    +for t in xrange(1000):
    +    messages.append(message(i_message, random.randint(1, 5)))
    +    d = display()
    +    for text in messages:
    +        d.set_vertical(text.x, text.y, text)
    +        text.move()
    +    sys.stdout.write(str(d))
    +    sys.stdout.flush()
    +    del d
    +    time.sleep(0.1)
     

    Ejemplo:

    -
    juan@maverick:~$ /usr/bin/env python matrix.py
    -Input a message: PYTHON
    +
    juan@maverick:~$ /usr/bin/env python matrix.py
    +Input a message: PYTHON
     
    diff --git a/recetario/multiprocessingythreading/index.html b/recetario/multiprocessingythreading/index.html index 172051d12..e642a0e5d 100644 --- a/recetario/multiprocessingythreading/index.html +++ b/recetario/multiprocessingythreading/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +
    @@ -86,189 +86,189 @@

    Multiprocessing Y Threading

    En esta receta se muestra cómo hacer para correr algo en otro thread o proceso con pocos cambios y cómo lograr comunicación entre ellos.

    Notar que el pid de quién lanza doer es distinto al que imprime doer

    Ejemplo con Multiprocessing

    -
    import os
    -import sys
    -
    -from multiprocessing import Process
    -from multiprocessing import Queue
    -
    -class Doer(Process):
    -
    -    def __init__(self, queue, state=None):
    -        Process.__init__(self)
    -        self.queue = queue
    -        self.state = state
    -
    -    def _do_on_start(self):
    -        print "doint stuff on start"
    -        print "state:", self.state
    -        print "pid:", os.getpid()
    -        print
    -
    -    def _on_end(self):
    -        print "doint stuff on end"
    -        print "state:", self.state
    -        print "pid:", os.getpid()
    -        print
    -
    -    def run(self):
    -        self._do_on_start()
    -
    -        msg = None
    -        while msg is None or msg != "exit":
    -            # blocks here
    -            msg = self.queue.get()
    -            print "handling message", msg
    -
    -            # do stuff here according to the message
    -            if msg == "ping":
    -                print "pong"
    -            elif isinstance(msg, tuple) and len(msg) == 2:
    -                action, value = msg
    -                if action == "set-state":
    -                    self.state = value
    -                    print "new state:", self.state
    -            elif msg != "exit":
    -                print "unknown message", msg
    -
    -            print
    -
    -        self._on_end()
    -
    -def demo():
    -    queue = Queue()
    -    print "creating doer from process", os.getpid()
    -    doer = Doer(queue, 42)
    -    doer.start()
    -    queue.put("ping")
    -    queue.put("foo")
    -    queue.put(("set-state", "hola!"))
    -
    -    queue.put("exit")
    -
    -    doer.join()
    -
    -if __name__ == "__main__":
    -    demo()
    +
    import os
    +import sys
    +
    +from multiprocessing import Process
    +from multiprocessing import Queue
    +
    +class Doer(Process):
    +
    +    def __init__(self, queue, state=None):
    +        Process.__init__(self)
    +        self.queue = queue
    +        self.state = state
    +
    +    def _do_on_start(self):
    +        print "doint stuff on start"
    +        print "state:", self.state
    +        print "pid:", os.getpid()
    +        print
    +
    +    def _on_end(self):
    +        print "doint stuff on end"
    +        print "state:", self.state
    +        print "pid:", os.getpid()
    +        print
    +
    +    def run(self):
    +        self._do_on_start()
    +
    +        msg = None
    +        while msg is None or msg != "exit":
    +            # blocks here
    +            msg = self.queue.get()
    +            print "handling message", msg
    +
    +            # do stuff here according to the message
    +            if msg == "ping":
    +                print "pong"
    +            elif isinstance(msg, tuple) and len(msg) == 2:
    +                action, value = msg
    +                if action == "set-state":
    +                    self.state = value
    +                    print "new state:", self.state
    +            elif msg != "exit":
    +                print "unknown message", msg
    +
    +            print
    +
    +        self._on_end()
    +
    +def demo():
    +    queue = Queue()
    +    print "creating doer from process", os.getpid()
    +    doer = Doer(queue, 42)
    +    doer.start()
    +    queue.put("ping")
    +    queue.put("foo")
    +    queue.put(("set-state", "hola!"))
    +
    +    queue.put("exit")
    +
    +    doer.join()
    +
    +if __name__ == "__main__":
    +    demo()
     

    corriendolo tenemos el resultado

    -
    $ python controlled.py
    -creating doer from process 11784
    -doint stuff on start
    -state: 42
    -pid: 11785
    -
    -handling message ping
    -pong
    -
    -handling message foo
    -unknown message foo
    -
    -handling message ('set-state', 'hola!')
    -new state: hola!
    -
    -handling message exit
    -
    -doint stuff on end
    -state: hola!
    -pid: 11785
    +
    $ python controlled.py
    +creating doer from process 11784
    +doint stuff on start
    +state: 42
    +pid: 11785
    +
    +handling message ping
    +pong
    +
    +handling message foo
    +unknown message foo
    +
    +handling message ('set-state', 'hola!')
    +new state: hola!
    +
    +handling message exit
    +
    +doint stuff on end
    +state: hola!
    +pid: 11785
     

    Ejemplo con Threading

    Para hacerlo andar con threading hay que solo cambiar de donde importamos las cosas, aquí esta la diferencia:

    Notar que el pid de quién lanza doer es igual al que imprime doer.

    -
    diff controlled.py controlledthread.py
    -4,5c4,5
    -< from multiprocessing import Process
    -< from multiprocessing import Queue
    ----
    -> from threading import Thread as Process
    -> from Queue import Queue
    +
    diff controlled.py controlledthread.py
    +4,5c4,5
    +< from multiprocessing import Process
    +< from multiprocessing import Queue
    +---
    +> from threading import Thread as Process
    +> from Queue import Queue
     
    -
    import os
    -import sys
    -
    -from threading import Thread as Process
    -from Queue import Queue
    -
    -class Doer(Process):
    -
    -    def __init__(self, queue, state=None):
    -        Process.__init__(self)
    -        self.queue = queue
    -        self.state = state
    -
    -    def _do_on_start(self):
    -        print "doint stuff on start"
    -        print "state:", self.state
    -        print "pid:", os.getpid()
    -        print
    -
    -    def _on_end(self):
    -        print "doint stuff on end"
    -        print "state:", self.state
    -        print "pid:", os.getpid()
    -        print
    -
    -    def run(self):
    -        self._do_on_start()
    -
    -        msg = None
    -        while msg is None or msg != "exit":
    -            # blocks here
    -            msg = self.queue.get()
    -            print "handling message", msg
    -
    -            # do stuff here according to the message
    -            if msg == "ping":
    -                print "pong"
    -            elif isinstance(msg, tuple) and len(msg) == 2:
    -                action, value = msg
    -                if action == "set-state":
    -                    self.state = value
    -                    print "new state:", self.state
    -            elif msg != "exit":
    -                print "unknown message", msg
    -
    -            print
    -
    -        self._on_end()
    -
    -def demo():
    -    queue = Queue()
    -    print "creating doer from process", os.getpid()
    -    doer = Doer(queue, 42)
    -    doer.start()
    -    queue.put("ping")
    -    queue.put("foo")
    -    queue.put(("set-state", "hola!"))
    -
    -    queue.put("exit")
    -
    -    doer.join()
    -
    -if __name__ == "__main__":
    -    demo()
    +
    import os
    +import sys
    +
    +from threading import Thread as Process
    +from Queue import Queue
    +
    +class Doer(Process):
    +
    +    def __init__(self, queue, state=None):
    +        Process.__init__(self)
    +        self.queue = queue
    +        self.state = state
    +
    +    def _do_on_start(self):
    +        print "doint stuff on start"
    +        print "state:", self.state
    +        print "pid:", os.getpid()
    +        print
    +
    +    def _on_end(self):
    +        print "doint stuff on end"
    +        print "state:", self.state
    +        print "pid:", os.getpid()
    +        print
    +
    +    def run(self):
    +        self._do_on_start()
    +
    +        msg = None
    +        while msg is None or msg != "exit":
    +            # blocks here
    +            msg = self.queue.get()
    +            print "handling message", msg
    +
    +            # do stuff here according to the message
    +            if msg == "ping":
    +                print "pong"
    +            elif isinstance(msg, tuple) and len(msg) == 2:
    +                action, value = msg
    +                if action == "set-state":
    +                    self.state = value
    +                    print "new state:", self.state
    +            elif msg != "exit":
    +                print "unknown message", msg
    +
    +            print
    +
    +        self._on_end()
    +
    +def demo():
    +    queue = Queue()
    +    print "creating doer from process", os.getpid()
    +    doer = Doer(queue, 42)
    +    doer.start()
    +    queue.put("ping")
    +    queue.put("foo")
    +    queue.put(("set-state", "hola!"))
    +
    +    queue.put("exit")
    +
    +    doer.join()
    +
    +if __name__ == "__main__":
    +    demo()
     
    -
    $ python controlledthread.py
    -creating doer from process 11812
    -doint stuff on start
    -state: 42
    -pid: 11812
    -
    -handling message ping
    -pong
    -
    -handling message foo
    -unknown message foo
    -
    -handling message ('set-state', 'hola!')
    -new state: hola!
    -
    -handling message exit
    -
    -doint stuff on end
    -state: hola!
    -pid: 11812
    +
    $ python controlledthread.py
    +creating doer from process 11812
    +doint stuff on start
    +state: 42
    +pid: 11812
    +
    +handling message ping
    +pong
    +
    +handling message foo
    +unknown message foo
    +
    +handling message ('set-state', 'hola!')
    +new state: hola!
    +
    +handling message exit
    +
    +doint stuff on end
    +state: hola!
    +pid: 11812
     
    diff --git a/recetario/normalizarcaracteresunicode/index.html b/recetario/normalizarcaracteresunicode/index.html index 8c6115827..b1df6a1c0 100644 --- a/recetario/normalizarcaracteresunicode/index.html +++ b/recetario/normalizarcaracteresunicode/index.html @@ -24,7 +24,7 @@ - +Ir al contenido principal @@ -58,12 +58,12 @@ - + @@ -83,28 +83,28 @@

    La Cuestión

    Al efectuar búsquedas en Internet, estamos acostumbrados a que no se distinga entre mayúsculas y minúsculas, y que se ignoren los acentos de las palabras. Para hacer esto en Python, antes que nada necesitamos una función que convierta los strings a la forma especificada. Una que haga lo siguiente:

    -
    >>> normalizar_string(u'Mónica Viñao')
    -'monica vinao'
    +
    >>> normalizar_string(u'Mónica Viñao')
    +'monica vinao'
     

    Usando unicodedata.normalize

    Unicode define equivalencias entre caracteres, o secuencias de caracteres, de los distintos estándares (ver http://en.wikipedia.org/wiki/Unicode_equivalence). Y define formas normales a las que podemos llevar un texto. Entonces podemos lograr la transformación que queremos haciendo una normalización. Los caracteres se descomponen, ignorando la parte que no es ASCII:

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -
    -from unicodedata import normalize
    -
    -def normalizar_string(unicode_string):
    -    u"""Retorna unicode_string normalizado para efectuar una búsqueda.
    -
    -    >>> normalizar_string(u'Mónica Viñao')
    -    'monica vinao'
    -
    -    """
    -    return normalize('NFKD', unicode_string).encode('ASCII', 'ignore').lower()
    -
    -if __name__ == "__main__":
    -    import doctest
    -    doctest.testmod()
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +
    +from unicodedata import normalize
    +
    +def normalizar_string(unicode_string):
    +    u"""Retorna unicode_string normalizado para efectuar una búsqueda.
    +
    +    >>> normalizar_string(u'Mónica Viñao')
    +    'monica vinao'
    +
    +    """
    +    return normalize('NFKD', unicode_string).encode('ASCII', 'ignore').lower()
    +
    +if __name__ == "__main__":
    +    import doctest
    +    doctest.testmod()
     

    ¡Gracias a Martin Conte Mac Donell!

    diff --git a/recetario/notificardispositivosusb/index.html b/recetario/notificardispositivosusb/index.html index af42cd1cd..123969fe2 100644 --- a/recetario/notificardispositivosusb/index.html +++ b/recetario/notificardispositivosusb/index.html @@ -33,7 +33,7 @@ # def callback(c"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - +
    @@ -94,35 +94,35 @@

    Detectar Y Notificar Dispositivos Usb

    • Cómo Detectar y notificar dispositivos USB, usando Python, en Linux, ejemplo simple.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -import glib
    -import gudev
    -import pynotify
    -import sys
    -#
    -def callback(client, action, device, user_data):
    -    device_vendor = device.get_property("ID_VENDOR_ENC")
    -    device_model = device.get_property("ID_MODEL_ENC")
    -    if action == "add":
    -        n = pynotify.Notification("USB Device Added", "%s %s is now connected "
    -                                  "to your system" % (device_vendor,
    -                                  device_model))
    -        n.show()
    -    elif action == "remove":
    -        n = pynotify.Notification("USB Device Removed", "%s %s has been "
    -                                  "disconnected from your system" %
    -                                  (device_vendor, device_model))
    -        n.show()
    -#
    -if not pynotify.init("USB Device Notifier"):
    -    sys.exit("Couldn't connect to the notification daemon!")
    -#
    -client = gudev.Client(["usb/usb_device"])
    -client.connect("uevent", callback, None)
    -#
    -loop = glib.MainLoop()
    -loop.run()
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +import glib
    +import gudev
    +import pynotify
    +import sys
    +#
    +def callback(client, action, device, user_data):
    +    device_vendor = device.get_property("ID_VENDOR_ENC")
    +    device_model = device.get_property("ID_MODEL_ENC")
    +    if action == "add":
    +        n = pynotify.Notification("USB Device Added", "%s %s is now connected "
    +                                  "to your system" % (device_vendor,
    +                                  device_model))
    +        n.show()
    +    elif action == "remove":
    +        n = pynotify.Notification("USB Device Removed", "%s %s has been "
    +                                  "disconnected from your system" %
    +                                  (device_vendor, device_model))
    +        n.show()
    +#
    +if not pynotify.init("USB Device Notifier"):
    +    sys.exit("Couldn't connect to the notification daemon!")
    +#
    +client = gudev.Client(["usb/usb_device"])
    +client.connect("uevent", callback, None)
    +#
    +loop = glib.MainLoop()
    +loop.run()
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    Fe de Erratas: seguramente hay una forma mejor de hacerlo, pero esta funciona correctamente.

    diff --git a/recetario/obtenerbytestransferidos/index.html b/recetario/obtenerbytestransferidos/index.html index 93b6601b9..cc7910067 100644 --- a/recetario/obtenerbytestransferidos/index.html +++ b/recetario/obtenerbytestransferidos/index.html @@ -28,7 +28,7 @@ if interface in line: data = line.split('%s:' % interf"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    @@ -87,18 +87,18 @@

    Obtener La Cantidad De Bytes Transferidos

    Imprime la cantidad de datos en Bytes transferidos en la interfaz indicada.

    -
    interface= 'eth0'
    -for line in open('/proc/net/dev', 'r'):
    -    if interface in line:
    -        data = line.split('%s:' % interface)[1].split()
    -        rx_bytes, tx_bytes = (data[0], data[8])
    -print '%s bytes received' % rx_bytes
    -print '%s bytes sent' % tx_bytes
    +
    interface= 'eth0'
    +for line in open('/proc/net/dev', 'r'):
    +    if interface in line:
    +        data = line.split('%s:' % interface)[1].split()
    +        rx_bytes, tx_bytes = (data[0], data[8])
    +print '%s bytes received' % rx_bytes
    +print '%s bytes sent' % tx_bytes
     

    Ejemplo:

    -
    juan@maverick:~$ /usr/bin/env python prueba.py
    -2066696798 bytes received
    -169266445 bytes sent
    +
    juan@maverick:~$ /usr/bin/env python prueba.py
    +2066696798 bytes received
    +169266445 bytes sent
     
    diff --git a/recetario/obtenersensaciontermica/index.html b/recetario/obtenersensaciontermica/index.html index 27b9726f0..0e6fcde61 100644 --- a/recetario/obtenersensaciontermica/index.html +++ b/recetario/obtenersensaciontermica/index.html @@ -33,7 +33,7 @@ v = 20 # Velocidad del Viento "> - + Ir al contenido principal @@ -67,12 +67,12 @@ - +
    @@ -94,19 +94,19 @@

    Obtener Sensacion Termica

    • Cómo obtener la Sensación Térmica o Temperatura Aparente usando Python, ejemplo simple.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -import math
    -
    -t= 20 # Temperatura
    -v = 20 # Velocidad del Viento
    -st = 33 + (t- 33)*(0.474 + 0.454 * math.sqrt((v))-0.0454*v)
    -print st
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +import math
    +
    +t= 20 # Temperatura
    +v = 20 # Velocidad del Viento
    +st = 33 + (t- 33)*(0.474 + 0.454 * math.sqrt((v))-0.0454*v)
    +print st
     

    Ejemplo:

    -
    /usr/bin/env python st.py
    -12.24
    +
    /usr/bin/env python st.py
    +12.24
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    Fe de Erratas: seguramente hay una forma mejor de hacerlo, pero esta funciona correctamente.

    diff --git a/recetario/obtenerubicaciongeografica/index.html b/recetario/obtenerubicaciongeografica/index.html index de802cfcf..c63df8ea3 100644 --- a/recetario/obtenerubicaciongeografica/index.html +++ b/recetario/obtenerubicaciongeografica/index.html @@ -27,7 +27,7 @@ Requisitos: Base de Datos de Geo-Location en la misma ubicación que el programa, descargarla usando: wget"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - +
    @@ -89,43 +89,43 @@

    Obtener Ubicacion Geografica

  • Cómo obtener distintos datos de la ubicación Geográfica, usando Python-Geoip, ejemplo simple.

  • Requisitos: Base de Datos de Geo-Location en la misma ubicación que el programa, descargarla usando:

    -
    wget --verbose http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
    +
    wget --verbose http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
     

    Nota: Depende de la conectividad con Internet usando dirección ip public version 4, se desconoce el comportamiento con ip version 6.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -import urllib
    -try:
    -    import GeoIP
    -except ImportError:
    -    print(" ERROR: No PYTHON-GEOIP avaliable!!!. ") # que hacer si falla la importacion de la libreria
    -    pass
    -
    -# La base de datos GeoLiteCity.dat debe estar en la misma ubicacion que este programa
    -gi = GeoIP.open(
    -"GeoLiteCity.dat", GeoIP.GEOIP_INDEX_CACHE | GeoIP.GEOIP_CHECK_CACHE)
    -
    -# Obtiene la IP Publica
    -try:
    -    # esta URL puede ser reemplazada con otra que preste similar servicio
    -    ip = urllib.urlopen(
    -    'http://www.whatismyip.com/automation/n09230945.asp').read()
    -    print ip
    -except: # que hacer si falla la conectividad
    -    print ("ERROR: Network error!!!. ")
    -    pass
    -
    -# Obtiene los datos de la DataBase usando la IP Publica
    -data = gi.record_by_name(ip)
    -
    -# Imprime los datos en la linea de comandos
    -print data
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +import urllib
    +try:
    +    import GeoIP
    +except ImportError:
    +    print(" ERROR: No PYTHON-GEOIP avaliable!!!. ") # que hacer si falla la importacion de la libreria
    +    pass
    +
    +# La base de datos GeoLiteCity.dat debe estar en la misma ubicacion que este programa
    +gi = GeoIP.open(
    +"GeoLiteCity.dat", GeoIP.GEOIP_INDEX_CACHE | GeoIP.GEOIP_CHECK_CACHE)
    +
    +# Obtiene la IP Publica
    +try:
    +    # esta URL puede ser reemplazada con otra que preste similar servicio
    +    ip = urllib.urlopen(
    +    'http://www.whatismyip.com/automation/n09230945.asp').read()
    +    print ip
    +except: # que hacer si falla la conectividad
    +    print ("ERROR: Network error!!!. ")
    +    pass
    +
    +# Obtiene los datos de la DataBase usando la IP Publica
    +data = gi.record_by_name(ip)
    +
    +# Imprime los datos en la linea de comandos
    +print data
     

    Ejemplo:

    -
    /usr/bin/env python geolocation.py
    -190.17.169.XXX
    -{'city': 'XXXXXX', 'region_name': 'Buenos Aires', 'region': '01', 'area_code': 0, 'time_zone': 'America/Argentina/Buenos_Aires', 'longitude': -58.92079000071094, 'metro_code': 0, 'country_code3': 'ARG', 'latitude': -34.17680005629883, 'postal_code': None, 'dma_code': 0, 'country_code': 'AR', 'country_name': 'Argentina'}
    +
    /usr/bin/env python geolocation.py
    +190.17.169.XXX
    +{'city': 'XXXXXX', 'region_name': 'Buenos Aires', 'region': '01', 'area_code': 0, 'time_zone': 'America/Argentina/Buenos_Aires', 'longitude': -58.92079000071094, 'metro_code': 0, 'country_code3': 'ARG', 'latitude': -34.17680005629883, 'postal_code': None, 'dma_code': 0, 'country_code': 'AR', 'country_name': 'Argentina'}
     

    Colaboración: Si tenes conectividad con internet con ip version 6 NATIVA, puedes documentar tu experiencia aquí.

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    diff --git a/recetario/pasarrecaptcha/index.html b/recetario/pasarrecaptcha/index.html index ffe5cbdab..8baee883b 100644 --- a/recetario/pasarrecaptcha/index.html +++ b/recetario/pasarrecaptcha/index.html @@ -27,7 +27,7 @@ En este caso vamos a probarlo este código con esta demo api: https://www.google.com/recaptcha/api2/demo ."> - + Ir al contenido principal @@ -61,12 +61,12 @@ - +
    @@ -96,62 +96,62 @@

    Pasarrecaptcha.rst

    ## Implementación

    Realizamos un polling (hace referencia a una operación de consulta constante) para cuando aparezca la imagen de la api demo. Por eso está tomando screenshot de la pantalla cada cierto período de tiempo hasta encontrarlo. Sino lo encuentra después de un cierto valor máximo de tiempo, se detiene la ejecución. Y una vez que encuentra la ventana de la api, hará un rectángulo negro alrededor del objeto "I'm not a robot" detectado y terminará el polling.

    -
    import pyautogui
    -import cv2
    -import time
    -
    -# Cargar plantilla o imagen de referencia
    -plantilla = cv2.imread("./captcha.jpg",0)
    -w, h = plantilla.shape[::-1]
    -
    -# Valores de inicializacion
    -min_val = 1     #min_val ronda en valores menores a 1
    -cont = 0
    -contMax=60
    -delay = 1       #1 segundos
    -
    -while ((min_val > 0.015) or (cont==contMax)):      #Generelmente 0.015... es el valor que devuelve cuando no encuentra el objeto
    -
    -    # Realizar screenshot de la pantalla para analizarla
    -    imagen = pyautogui.screenshot()
    -    # Para guardar cada screenshot
    -    imagen.save("screenshot.png")
    -
    -    imagenCopy = cv2.imread("screenshot.png",0)
    -
    -    metodo = eval('cv2.TM_SQDIFF_NORMED')
    -
    -    # Aplicar coincidencia de plantillas
    -    res = cv2.matchTemplate(imagenCopy,plantilla,metodo)
    -    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    -
    -    top_left = min_loc
    -    bottom_right = (top_left[0] + w, top_left[1] + h)
    -
    -    cont=cont+1
    -    time.sleep(delay)
    -
    -    print(min_val)
    -
    -    if (min_val < 0.015):
    -        # Colocar un rectangulo en la imagen blanco y negro -> solo tiene un canal por eso aparece 0
    -        # (El rectangulo queda con una especie de color negro en la imagen)
    -        cv2.rectangle(imagenCopy,top_left, bottom_right, 0, 8)
    -        cv2.imwrite("./coincidencia.png",imagenCopy)
    +
    import pyautogui
    +import cv2
    +import time
    +
    +# Cargar plantilla o imagen de referencia
    +plantilla = cv2.imread("./captcha.jpg",0)
    +w, h = plantilla.shape[::-1]
    +
    +# Valores de inicializacion
    +min_val = 1     #min_val ronda en valores menores a 1
    +cont = 0
    +contMax=60
    +delay = 1       #1 segundos
    +
    +while ((min_val > 0.015) or (cont==contMax)):      #Generelmente 0.015... es el valor que devuelve cuando no encuentra el objeto
    +
    +    # Realizar screenshot de la pantalla para analizarla
    +    imagen = pyautogui.screenshot()
    +    # Para guardar cada screenshot
    +    imagen.save("screenshot.png")
    +
    +    imagenCopy = cv2.imread("screenshot.png",0)
    +
    +    metodo = eval('cv2.TM_SQDIFF_NORMED')
    +
    +    # Aplicar coincidencia de plantillas
    +    res = cv2.matchTemplate(imagenCopy,plantilla,metodo)
    +    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    +
    +    top_left = min_loc
    +    bottom_right = (top_left[0] + w, top_left[1] + h)
    +
    +    cont=cont+1
    +    time.sleep(delay)
    +
    +    print(min_val)
    +
    +    if (min_val < 0.015):
    +        # Colocar un rectangulo en la imagen blanco y negro -> solo tiene un canal por eso aparece 0
    +        # (El rectangulo queda con una especie de color negro en la imagen)
    +        cv2.rectangle(imagenCopy,top_left, bottom_right, 0, 8)
    +        cv2.imwrite("./coincidencia.png",imagenCopy)
     

    Este es el resultado:

    /images/Recetario/pasarrecaptcha/coincidencia.png

    Una vez detectado el objeto "I'm not a robot" se procede a posicionar el mouse donde éste se encuentre y se procede a dar click.

    -
    import pyautogui
    -
    -# Ingresar imagen que debemos buscar
    -reCAPTCHAlocation = pyautogui.locateOnScreen('captcha.jpg')
    -
    -# Posiciones donde se encuentra el elemento buscado
    -reCAPTCHApoint = pyautogui.center(reCAPTCHAlocation)
    -reCAPTCHAx, reCAPTCHAy = reCAPTCHApoint
    -
    -# Hacer click en las coordenadas encontradas
    -pyautogui.click(reCAPTCHAx, reCAPTCHAy)
    +
    import pyautogui
    +
    +# Ingresar imagen que debemos buscar
    +reCAPTCHAlocation = pyautogui.locateOnScreen('captcha.jpg')
    +
    +# Posiciones donde se encuentra el elemento buscado
    +reCAPTCHApoint = pyautogui.center(reCAPTCHAlocation)
    +reCAPTCHAx, reCAPTCHAy = reCAPTCHApoint
    +
    +# Hacer click en las coordenadas encontradas
    +pyautogui.click(reCAPTCHAx, reCAPTCHAy)
     
    /images/Recetario/pasarrecaptcha/resultado.png

    ¡Enhorabuena! Lograste superar el reCAPTCHA.

    diff --git a/recetario/progressbarurllib2/index.html b/recetario/progressbarurllib2/index.html index 0722e4ad9..3211574c5 100644 --- a/recetario/progressbarurllib2/index.html +++ b/recetario/progressbarurllib2/index.html @@ -27,7 +27,7 @@ from progressbar import Percentage from progressbar import "> - + Ir al contenido principal @@ -61,12 +61,12 @@ - +
    @@ -86,32 +86,32 @@

    Progressbar Y Urllib2

    Este es un ejemplito de cómo descargar algo y a medida que se descarga, mostrar una barrita de progreso.

    -
    from progressbar import ProgressBar
    -from progressbar import Percentage
    -from progressbar import Bar
    -
    -
    -def download_python():
    -    url = 'http://www.python.org/ftp/python/2.7/Python-2.7.tar.bz2'
    -    fname = url.split('/')[-1]
    -    u = urllib2.urlopen(url)
    -    file = open(fname, 'w')
    -    meta = u.info()
    -    file_size = int(meta.getheaders("Content-Length")[0])
    -    print "Descargando: %s Bytes: %s" % (fname, file_size)
    -    pbar = ProgressBar(widgets=[Percentage(), Bar()], maxval=file_size).start()
    -    i = 0
    -    chunk = 10240
    -    while True:
    -        buffer = u.read(chunk)
    -        if buffer:
    -            file.write(buffer)
    -            pbar.update(i)
    -            i += chunk
    -        else:
    -            break
    -    pbar.finish()
    -    file.close()
    +
    from progressbar import ProgressBar
    +from progressbar import Percentage
    +from progressbar import Bar
    +
    +
    +def download_python():
    +    url = 'http://www.python.org/ftp/python/2.7/Python-2.7.tar.bz2'
    +    fname = url.split('/')[-1]
    +    u = urllib2.urlopen(url)
    +    file = open(fname, 'w')
    +    meta = u.info()
    +    file_size = int(meta.getheaders("Content-Length")[0])
    +    print "Descargando: %s Bytes: %s" % (fname, file_size)
    +    pbar = ProgressBar(widgets=[Percentage(), Bar()], maxval=file_size).start()
    +    i = 0
    +    chunk = 10240
    +    while True:
    +        buffer = u.read(chunk)
    +        if buffer:
    +            file.write(buffer)
    +            pbar.update(i)
    +            i += chunk
    +        else:
    +            break
    +    pbar.finish()
    +    file.close()
     
    diff --git a/recetario/psycospeedup/index.html b/recetario/psycospeedup/index.html index a05538dea..1a9a79793 100644 --- a/recetario/psycospeedup/index.html +++ b/recetario/psycospeedup/index.html @@ -32,7 +32,7 @@ print(" ") '> - + Ir al contenido principal @@ -66,12 +66,12 @@ - +
    @@ -91,19 +91,19 @@

    Psycospeedup

    Acelera las aplicaciones en Python (JIT), disponible para 32bit.

    -
    #!/usr/bin/env python
    -#-*- coding:utf-8 -*-
    -try:
    -    import psyco  # Speed Up :)
    -    psyco.full()
    -except ImportError:
    -    print(" ")
    -    print(" No PYTHON-PSYCO avaliable, this application will run slower... ") # imprime este mensaje si Psyco no esta disponible
    -    print(" ")
    -    pass
    -# la aplicacion continuara funcionando si psyco no esta disponible, asi mismo continuara si es 64bit
    -########################## imports goes here
    -# from foo import bar
    +
    #!/usr/bin/env python
    +#-*- coding:utf-8 -*-
    +try:
    +    import psyco  # Speed Up :)
    +    psyco.full()
    +except ImportError:
    +    print(" ")
    +    print(" No PYTHON-PSYCO avaliable, this application will run slower... ") # imprime este mensaje si Psyco no esta disponible
    +    print(" ")
    +    pass
    +# la aplicacion continuara funcionando si psyco no esta disponible, asi mismo continuara si es 64bit
    +########################## imports goes here
    +# from foo import bar
     
    diff --git a/recetario/pythoncard/index.html b/recetario/pythoncard/index.html index ad33787a0..cd36d93a7 100644 --- a/recetario/pythoncard/index.html +++ b/recetario/pythoncard/index.html @@ -26,7 +26,7 @@ PythonCard es un conjunto de herramientas de construcción GUI para crear aplicaciones de escritorio multiplataforma en Windows, Mac OS X, y Linux, usando Python. La motivación de PythonCa"> - +Ir al contenido principal @@ -60,12 +60,12 @@ - + @@ -92,7 +92,7 @@

    Pythoncard

    Cómo instalar PythonCard:

    Linux (Debian y derivados)

    Pythoncard esta soportado en Etch, así que su instalación es bastante simple.

    -
    apt-get install pythoncard
    +
    apt-get install pythoncard
     

    Windows

      @@ -111,15 +111,15 @@

      Pythoncard

    • Varios: mp3player, slideshow (presentaciones html), sounds (sonidos wab), textIndexer, worldclock

    Si algo anda mal y no se muestra la pantalla de ejemplos, podemos probar lo siguiente para ver que esta fallando en una consola Python:

    -
    import wx
    -wx.version() # debería imprimir '2.8.7.1 (msw-unicode)' o similar
    -
    -from PythonCard import model
    -rsrc = {'application':{'type':'Application', 'name':'Minimal',
    -    'backgrounds': [{'type':'Background','name':'bgMin',
    -        'title':'Prueba','size':(200, 100),'components': []}]} }
    -
    -model.Application(model.Background, None, rsrc).MainLoop()
    +
    import wx
    +wx.version() # debería imprimir '2.8.7.1 (msw-unicode)' o similar
    +
    +from PythonCard import model
    +rsrc = {'application':{'type':'Application', 'name':'Minimal',
    +    'backgrounds': [{'type':'Background','name':'bgMin',
    +        'title':'Prueba','size':(200, 100),'components': []}]} }
    +
    +model.Application(model.Background, None, rsrc).MainLoop()
     

    Debería aparecer una ventanita con título "Prueba".

    Además, PythonCard dispone de características de depuración (depurar menú, loggeo, visor de mensajes, visor del espacio nombres, editor de propiedades, shell). Estas opciones se pueden activar al ejecutar los ejemplos para ver cómo funcionan.

    @@ -177,29 +177,29 @@

    Pythoncard

  • De no funcionar, se pueden cambiar las opciones de depuración en el menú File, Run Options o ejecutar con el interprete con la opción Run with interpreter

  • Código completo final del ejemplo:

    -
    from PythonCard import model
    -from PythonCard import dialog
    -
    -class MyBackground(model.Background):
    -
    -    def on_initialize(self, event):
    -        # if you have any initialization
    -        # including sizer setup, do it here
    -        pass
    -
    -    def on_btnEjecutar_mouseClick(self, event):
    -        comando = self.components.txtComando.text
    -        resultado = str(eval(comando))
    -        self.components.txtResultados.text = resultado
    -
    -    def on_menuFileAyuda_select(self, event):
    -        dialog.alertDialog(self,
    -            'Este programa de prueba ejecuta el comando ingresado por el usuario',
    -            'Ayuda')
    -
    -if __name__ == '__main__':
    -    app = model.Application(MyBackground)
    -    app.MainLoop()
    +
    from PythonCard import model
    +from PythonCard import dialog
    +
    +class MyBackground(model.Background):
    +
    +    def on_initialize(self, event):
    +        # if you have any initialization
    +        # including sizer setup, do it here
    +        pass
    +
    +    def on_btnEjecutar_mouseClick(self, event):
    +        comando = self.components.txtComando.text
    +        resultado = str(eval(comando))
    +        self.components.txtResultados.text = resultado
    +
    +    def on_menuFileAyuda_select(self, event):
    +        dialog.alertDialog(self,
    +            'Este programa de prueba ejecuta el comando ingresado por el usuario',
    +            'Ayuda')
    +
    +if __name__ == '__main__':
    +    app = model.Application(MyBackground)
    +    app.MainLoop()
     

    Nota: Por ser un ejemplo se obviaron temas de manejo de excepciones y cuestiones avanzadas. Se pueden descargar los archivos terminados:

      diff --git a/recetario/pythonversioncheck/index.html b/recetario/pythonversioncheck/index.html index b53d3b7d6..ebb6bd2f4 100644 --- a/recetario/pythonversioncheck/index.html +++ b/recetario/pythonversioncheck/index.html @@ -26,7 +26,7 @@ if sys.hexversion > 0x02060000: # Python version check print "\n Python version > 2.6.0\n" # Aca va que hacer si es mayor'> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -85,15 +85,15 @@

    Python Version Check

    Chequear la versión de Python, y salir o imprimir error en funcion de eso.

    -
    if sys.hexversion > 0x02060000: # Python version check
    -    print "\n Python version > 2.6.0\n" # Aca va que hacer si es mayor, continua
    -else:
    -    print "\n ERROR: Python version < 2.6.0\n" # Aca va que hacer si es menor, error
    +
    if sys.hexversion > 0x02060000: # Python version check
    +    print "\n Python version > 2.6.0\n" # Aca va que hacer si es mayor, continua
    +else:
    +    print "\n ERROR: Python version < 2.6.0\n" # Aca va que hacer si es menor, error
     

    Ejemplo:

    -
    juan@maverick:~$ /usr/bin/env python test.py
    -
    - Python version > 2.6.0
    +
    juan@maverick:~$ /usr/bin/env python test.py
    +
    + Python version > 2.6.0
     
    diff --git a/recetario/pyuno/holamundo/index.html b/recetario/pyuno/holamundo/index.html index 0ea60c8e0..c17ee179d 100644 --- a/recetario/pyuno/holamundo/index.html +++ b/recetario/pyuno/holamundo/index.html @@ -33,7 +33,7 @@ def msgbox(message): ctx = uno.getComponentContext("> - + Ir al contenido principal @@ -67,12 +67,12 @@ - +
    @@ -92,24 +92,24 @@

    Holamundo

    Todo un clásico... un Hola Mundo desde pyUNO

    -
    # -*- coding: utf-8 -*-
    -import uno
    -
    -def hola_mundo():
    -    msgbox('Hola Mundo en PyUNO')
    -    return
    -
    -def msgbox(message):
    -    ctx = uno.getComponentContext()
    -    sm = ctx.getServiceManager()
    -    toolkit = sm.createInstanceWithContext('com.sun.star.awt.Toolkit', ctx)
    -    msg = toolkit.createMessageBox(
    -                                toolkit.getDesktopWindow(),
    -                                'infobox',
    -                                1,
    -                                'UNOPython',
    -                                str(message))
    -    return msg.execute()
    +
    # -*- coding: utf-8 -*-
    +import uno
    +
    +def hola_mundo():
    +    msgbox('Hola Mundo en PyUNO')
    +    return
    +
    +def msgbox(message):
    +    ctx = uno.getComponentContext()
    +    sm = ctx.getServiceManager()
    +    toolkit = sm.createInstanceWithContext('com.sun.star.awt.Toolkit', ctx)
    +    msg = toolkit.createMessageBox(
    +                                toolkit.getDesktopWindow(),
    +                                'infobox',
    +                                1,
    +                                'UNOPython',
    +                                str(message))
    +    return msg.execute()
     

    Para saber donde guardar esta macro, mira el wiki de Apache OpenOffice: http://wiki.openoffice.org/wiki/ES/Manuales/GuiaAOO/TemasAvanzados/Macros/Python

    Para ejecutar la macro, desde cualquier aplicación de Apache OpenOffice, menú Herramientas -> Macros -> Ejecutar macros...

    diff --git a/recetario/pyuno/miprimermacro/index.html b/recetario/pyuno/miprimermacro/index.html index 770c8f78b..494a9957b 100644 --- a/recetario/pyuno/miprimermacro/index.html +++ b/recetario/pyuno/miprimermacro/index.html @@ -29,7 +29,7 @@ def quien_soy(): doc = XSCRIPTCONTEXT.getDocument("> - + Ir al contenido principal @@ -63,12 +63,12 @@ - +
    @@ -88,42 +88,42 @@

    Miprimermacro

    La siguiente macro, detecta el tipo de documento (Calc, Writer, Draw, Impress, etc) desde el cual se ejecuta.

    -
    # -*- coding: utf-8 -*-
    -import uno
    -
    -def quien_soy():
    -    doc = XSCRIPTCONTEXT.getDocument()
    -    msgbox(obtener_tipo(doc))
    -    return
    -
    -def obtener_tipo(doc):
    -    tipo = {'com.sun.star.sheet.SpreadsheetDocument': 'Calc',
    -            'com.sun.star.text.TextDocument': 'Writer',
    -            'com.sun.star.presentation.PresentationDocument': 'Impress',
    -            'com.sun.star.drawing.DrawingDocument': 'Draw',
    -            'com.sun.star.sdb.OfficeDatabaseDocument': 'Base',
    -            'com.sun.star.formula.FormulaProperties': 'Math',
    -            'com.sun.star.script.BasicIDE': 'Basic'}
    -    # iteramos entre los tipos de documentos
    -    for t in tipo:
    -        # validamos si soporta el servicio
    -        if doc.supportsService(t):
    -            # devolvemos el tipo de documento
    -            return 'Soy %s' % tipo[t]
    -    # si termina sin encontrar un tipo
    -    return 'No se que tipo soy'
    -
    -def msgbox(message):
    -    ctx = uno.getComponentContext()
    -    sm = ctx.getServiceManager()
    -    toolkit = sm.createInstanceWithContext('com.sun.star.awt.Toolkit', ctx)
    -    msg = toolkit.createMessageBox(
    -                                toolkit.getDesktopWindow(),
    -                                'infobox',
    -                                1,
    -                                'UNOPython',
    -                                str(message))
    -    return msg.execute()
    +
    # -*- coding: utf-8 -*-
    +import uno
    +
    +def quien_soy():
    +    doc = XSCRIPTCONTEXT.getDocument()
    +    msgbox(obtener_tipo(doc))
    +    return
    +
    +def obtener_tipo(doc):
    +    tipo = {'com.sun.star.sheet.SpreadsheetDocument': 'Calc',
    +            'com.sun.star.text.TextDocument': 'Writer',
    +            'com.sun.star.presentation.PresentationDocument': 'Impress',
    +            'com.sun.star.drawing.DrawingDocument': 'Draw',
    +            'com.sun.star.sdb.OfficeDatabaseDocument': 'Base',
    +            'com.sun.star.formula.FormulaProperties': 'Math',
    +            'com.sun.star.script.BasicIDE': 'Basic'}
    +    # iteramos entre los tipos de documentos
    +    for t in tipo:
    +        # validamos si soporta el servicio
    +        if doc.supportsService(t):
    +            # devolvemos el tipo de documento
    +            return 'Soy %s' % tipo[t]
    +    # si termina sin encontrar un tipo
    +    return 'No se que tipo soy'
    +
    +def msgbox(message):
    +    ctx = uno.getComponentContext()
    +    sm = ctx.getServiceManager()
    +    toolkit = sm.createInstanceWithContext('com.sun.star.awt.Toolkit', ctx)
    +    msg = toolkit.createMessageBox(
    +                                toolkit.getDesktopWindow(),
    +                                'infobox',
    +                                1,
    +                                'UNOPython',
    +                                str(message))
    +    return msg.execute()
     

    Para saber donde guardar estas macros, mira el wiki de Apache OpenOffice: http://wiki.openoffice.org/wiki/ES/Manuales/GuiaAOO/TemasAvanzados/Macros/Python

    diff --git a/recetario/qt/qtextraertextorecurso/index.html b/recetario/qt/qtextraertextorecurso/index.html index 688bdc213..b13d2e8cd 100644 --- a/recetario/qt/qtextraertextorecurso/index.html +++ b/recetario/qt/qtextraertextorecurso/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    @@ -83,35 +83,35 @@

    Extraer Un Archivo De Texto Embebido En Un Recurso .qrc

    Además de poder embeber imágenes, la librería Qt (y por ende PyQt) también permite incluir otros elementos en su sistema de recursos. La función que se define a continuación permite leer los contenidos de un archivo de texto plano que se encuentre registrado en un archivo .qrc. Cabe agregar que antes de invocar a loadTextFileFromRc() hay que convertir el .qrc a módulo de Python con la herramienta pyrcc4 (por ejemplo, en una terminal de GNU/Linux: $ pyrcc4 -o resources.py resources.qrc). Esto puede ser útil para incorporar al programa una hoja de estilo que se aplique a toda la aplicación.

    -
    # -*- coding: utf-8 -*-
    -
    -
    -from PyQt4 import QtCore
    -
    -# El siguiente import realizará el registro de los recursos a PyQt.
    -import resources
    -
    -
    -def loadTextFileFromRc(rcPath):
    -    u"""Extrae el contenido de un archivo de texto incluido en el sistema
    -    de recursos.
    -
    -    Parámetros:
    -        rcPath: ruta absoluta del archivo dentro del recurso. Por ejemplo:
    -            ':/app/css/style.css'.
    -    """
    -
    -    q_file = QtCore.QFile(rcPath)
    -    q_file.open(QtCore.QIODevice.ReadOnly)
    -    q_text_stream = QtCore.QTextStream(q_file)
    -    content =  q_text_stream.readAll()
    -    q_file.close()
    -
    -    return content
    -
    -
    -if __name__ == '__main__':
    -    print loadTextFileFromRc(':/ruta/al/recurso.txt')
    +
    # -*- coding: utf-8 -*-
    +
    +
    +from PyQt4 import QtCore
    +
    +# El siguiente import realizará el registro de los recursos a PyQt.
    +import resources
    +
    +
    +def loadTextFileFromRc(rcPath):
    +    u"""Extrae el contenido de un archivo de texto incluido en el sistema
    +    de recursos.
    +
    +    Parámetros:
    +        rcPath: ruta absoluta del archivo dentro del recurso. Por ejemplo:
    +            ':/app/css/style.css'.
    +    """
    +
    +    q_file = QtCore.QFile(rcPath)
    +    q_file.open(QtCore.QIODevice.ReadOnly)
    +    q_text_stream = QtCore.QTextStream(q_file)
    +    content =  q_text_stream.readAll()
    +    q_file.close()
    +
    +    return content
    +
    +
    +if __name__ == '__main__':
    +    print loadTextFileFromRc(':/ruta/al/recurso.txt')
     
    diff --git a/recetario/qt/qtimprimirpagina/index.html b/recetario/qt/qtimprimirpagina/index.html index dcd27a651..d862999ba 100644 --- a/recetario/qt/qtimprimirpagina/index.html +++ b/recetario/qt/qtimprimirpagina/index.html @@ -33,7 +33,7 @@ web = QWebView() web.load(QU"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + @@ -92,31 +92,31 @@

    Qt Imprimir Pagina Web A Pdf

    Ejemplo de cómo imprimir una página web a pdf.

    -
    import sys
    -from PyQt4.QtCore import *
    -from PyQt4.QtGui import *
    -from PyQt4.QtWebKit import *
    -
    -app = QApplication(sys.argv)
    -
    -web = QWebView()
    - web.load(QUrl("http://www.google.com"))
    -
    -#web.show()
    -
    -printer = QPrinter()
    -printer.setPageSize(QPrinter.A4)
    -printer.setOutputFormat(QPrinter.PdfFormat)
    -printer.setOutputFileName("test.pdf")
    -
    -def convertIt():
    -   web.print_(printer)
    -   print "Pdf generated"
    -   QApplication.exit()
    -
    -QObject.connect(web, SIGNAL("loadFinished(bool)"), convertIt)
    -
    -sys.exit(app.exec_())
    +
    import sys
    +from PyQt4.QtCore import *
    +from PyQt4.QtGui import *
    +from PyQt4.QtWebKit import *
    +
    +app = QApplication(sys.argv)
    +
    +web = QWebView()
    + web.load(QUrl("http://www.google.com"))
    +
    +#web.show()
    +
    +printer = QPrinter()
    +printer.setPageSize(QPrinter.A4)
    +printer.setOutputFormat(QPrinter.PdfFormat)
    +printer.setOutputFileName("test.pdf")
    +
    +def convertIt():
    +   web.print_(printer)
    +   print "Pdf generated"
    +   QApplication.exit()
    +
    +QObject.connect(web, SIGNAL("loadFinished(bool)"), convertIt)
    +
    +sys.exit(app.exec_())
     
    diff --git a/recetario/qt/qtmultithread/index.html b/recetario/qt/qtmultithread/index.html index 924a2989c..f2816e760 100644 --- a/recetario/qt/qtmultithread/index.html +++ b/recetario/qt/qtmultithread/index.html @@ -30,7 +30,7 @@ #Modificado de la versión original de Mariano Guerra para GTK "> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + @@ -89,80 +89,80 @@

    Qt Multi Thread

    Ejemplo de cómo manipular la interfaz gráfica desde múltiples threads.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -
    -#qt_multithread.py
    -
    -#Modificado de la versión original de Mariano Guerra para GTK ( http://python.org.ar/pyar/GtkMultiThread )
    -#Versión para Qt por Ernesto Savoretti
    -
    -from PyQt4 import QtCore, QtGui
    -import time
    -import Queue
    -import random
    -import threading
    -import sys
    -
    -TEXTS = ['eggs', 'spam', 'pyar', 'gtk', 'qt']
    -
    -class Molesto(threading.Thread):
    -    '''un thread que quiere molestar el main thread'''
    -
    -    def __init__(self, cola):
    -        threading.Thread.__init__(self)
    -        self.setDaemon(True)
    -#        self.label = label # no usar en este thread!
    -
    -        self.cola = cola
    -
    -    def run(self):
    -        '''metodo principal del thread, duerme un tiempo aleatorio y despues
    -        pone algo en la cola para que el main thread lo haga'''
    -
    -        while True:
    -            time.sleep(random.random() * 5)
    -            texto = self.getName() + ' ' + random.choice(TEXTS)
    -            print self.getName(), 'escribiendo', texto
    -            self.cola.put(texto)
    -
    -class Ventana(QtGui.QWidget):
    -    '''ventana con un label, ninguna locura'''
    -
    -    def __init__(self, parent = None):
    -        QtGui.QWidget.__init__(self, parent)
    -        self.setGeometry(50, 50, 640, 480)
    -        self.setWindowTitle('Qt con threads')
    -        layout = QtGui.QHBoxLayout()
    -        self.label = QtGui.QLabel(self, text = '')
    -        layout.addWidget(self.label)
    -        self.setLayout(layout)
    -        self.cola = Queue.Queue()
    -        self.hincha_b = Molesto(self.cola)
    -
    -        self.hincha_b.start()
    -
    -        self.timer = QtCore.QTimer(self)
    -        self.timer.setInterval(100)
    -        self.timer.timeout.connect(self.queue_manager)
    -        self.timer.start()
    -        self.show()
    -
    -    def queue_manager(self):
    -        try:
    -            while True:
    -                texto = self.cola.get(True, 0.1)
    -                print texto
    -                self.label.setText(texto)
    -        except Queue.Empty:
    -            pass
    -
    -        return True
    -
    -if __name__ == '__main__':
    -    app = QtGui.QApplication(sys.argv)
    -    w = Ventana()
    -    app.exec_()
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +
    +#qt_multithread.py
    +
    +#Modificado de la versión original de Mariano Guerra para GTK ( http://python.org.ar/pyar/GtkMultiThread )
    +#Versión para Qt por Ernesto Savoretti
    +
    +from PyQt4 import QtCore, QtGui
    +import time
    +import Queue
    +import random
    +import threading
    +import sys
    +
    +TEXTS = ['eggs', 'spam', 'pyar', 'gtk', 'qt']
    +
    +class Molesto(threading.Thread):
    +    '''un thread que quiere molestar el main thread'''
    +
    +    def __init__(self, cola):
    +        threading.Thread.__init__(self)
    +        self.setDaemon(True)
    +#        self.label = label # no usar en este thread!
    +
    +        self.cola = cola
    +
    +    def run(self):
    +        '''metodo principal del thread, duerme un tiempo aleatorio y despues
    +        pone algo en la cola para que el main thread lo haga'''
    +
    +        while True:
    +            time.sleep(random.random() * 5)
    +            texto = self.getName() + ' ' + random.choice(TEXTS)
    +            print self.getName(), 'escribiendo', texto
    +            self.cola.put(texto)
    +
    +class Ventana(QtGui.QWidget):
    +    '''ventana con un label, ninguna locura'''
    +
    +    def __init__(self, parent = None):
    +        QtGui.QWidget.__init__(self, parent)
    +        self.setGeometry(50, 50, 640, 480)
    +        self.setWindowTitle('Qt con threads')
    +        layout = QtGui.QHBoxLayout()
    +        self.label = QtGui.QLabel(self, text = '')
    +        layout.addWidget(self.label)
    +        self.setLayout(layout)
    +        self.cola = Queue.Queue()
    +        self.hincha_b = Molesto(self.cola)
    +
    +        self.hincha_b.start()
    +
    +        self.timer = QtCore.QTimer(self)
    +        self.timer.setInterval(100)
    +        self.timer.timeout.connect(self.queue_manager)
    +        self.timer.start()
    +        self.show()
    +
    +    def queue_manager(self):
    +        try:
    +            while True:
    +                texto = self.cola.get(True, 0.1)
    +                print texto
    +                self.label.setText(texto)
    +        except Queue.Empty:
    +            pass
    +
    +        return True
    +
    +if __name__ == '__main__':
    +    app = QtGui.QApplication(sys.argv)
    +    w = Ventana()
    +    app.exec_()
     
    diff --git a/recetario/relojdigital/index.html b/recetario/relojdigital/index.html index 9bf4dbbc4..e7d8792ed 100644 --- a/recetario/relojdigital/index.html +++ b/recetario/relojdigital/index.html @@ -36,7 +36,7 @@ root.focus() root.title("ǝɯıʇ uoɥ'> - + Ir al contenido principal @@ -70,12 +70,12 @@ - + @@ -98,28 +98,28 @@

    Reloj Digital

  • Crear un Reloj digital simple, empleando un Label de TK.

  • Screenshot:

    -/images/RelojDigital/temp.jpg
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -from Tkinter import *
    -import time
    -#
    -root = Tk()
    -root.focus()
    -root.title("ǝɯıʇ uoɥʇʎd")
    -root.config(cursor='watch')
    -time1 = ''
    -clock = Label(root, font=('ubuntu', 30, 'bold'), bg='#3C3B37', fg='white', bd=0)
    -clock.pack(fill=BOTH, expand=1)
    -def tick():
    -    global time1
    -    time2 = time.strftime('%H:%M:%S')
    -    if time2 != time1:
    -        time1 = time2
    -        clock.config(text=time2)
    -    clock.after(200, tick)
    -tick()
    -root.mainloop()
    +/images/RelojDigital/temp.jpg
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +from Tkinter import *
    +import time
    +#
    +root = Tk()
    +root.focus()
    +root.title("ǝɯıʇ uoɥʇʎd")
    +root.config(cursor='watch')
    +time1 = ''
    +clock = Label(root, font=('ubuntu', 30, 'bold'), bg='#3C3B37', fg='white', bd=0)
    +clock.pack(fill=BOTH, expand=1)
    +def tick():
    +    global time1
    +    time2 = time.strftime('%H:%M:%S')
    +    if time2 != time1:
    +        time1 = time2
    +        clock.config(text=time2)
    +    clock.after(200, tick)
    +tick()
    +root.mainloop()
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    diff --git a/recetario/reverse/index.html b/recetario/reverse/index.html index a870a60af..1d182def3 100644 --- a/recetario/reverse/index.html +++ b/recetario/reverse/index.html @@ -29,7 +29,7 @@ def reverse(this): return ' '.join(''.join(list(t"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + @@ -90,17 +90,17 @@

    Reverse (A.k.a. "esrever")

    • Una humilde función para dar vuelta los caracteres usando Python, letras o números, ejemplo simple.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -def reverse(this):
    -    return ' '.join(''.join(list(things)[.. code-block:: python-1]) for things in this.split())
    -inputz = raw_input()
    -print reverse(inputz)
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +def reverse(this):
    +    return ' '.join(''.join(list(things)[.. code-block:: python-1]) for things in this.split())
    +inputz = raw_input()
    +print reverse(inputz)
     

    Ejemplo:

    -
    juan@wind:~$ /usr/bin/env python reverse.py
    -import antigravity
    -tropmi ytivargitna
    +
    juan@wind:~$ /usr/bin/env python reverse.py
    +import antigravity
    +tropmi ytivargitna
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    Fe de Erratas: seguramente hay una forma mejor de hacerlo, pero esta funciona correctamente.

    diff --git a/recetario/revisarconexion/index.html b/recetario/revisarconexion/index.html index 63dd8b7b4..85b47d7b1 100644 --- a/recetario/revisarconexion/index.html +++ b/recetario/revisarconexion/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +
    @@ -86,15 +86,15 @@

    Revisar Conexion

    Cómo revisar si tenemos conexión a internet.

    Para no depender de programas externos (tené en cuenta que, por ejemplo, ping seguramente no recibe los mismos parámetros en Linux que en Windows), podés intentar abrir un socket a algún servidor externo y enviar algo.

    Si el DNS resuelve podés chequear con socket.gethostbyname('google.com').

    -
    import socket
    -try:
    -    socket.gethostbyname('google.com')
    -    c = socket.create_connection(('google.com', 80), 1)
    -    c.close()
    -except socket.gaierror:
    -    print "DNS error"
    -except socket.error:
    -    print "Connection error"
    +
    import socket
    +try:
    +    socket.gethostbyname('google.com')
    +    c = socket.create_connection(('google.com', 80), 1)
    +    c.close()
    +except socket.gaierror:
    +    print "DNS error"
    +except socket.error:
    +    print "Connection error"
     
    diff --git a/recetario/rootcheck/index.html b/recetario/rootcheck/index.html index 4040442ce..e7375694c 100644 --- a/recetario/rootcheck/index.html +++ b/recetario/rootcheck/index.html @@ -28,7 +28,7 @@ if os.geteuid()==0: # "> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + @@ -90,19 +90,19 @@

    Root Check

    • Toda aplicación que NO requiera privilegios elevados no debería poder ejecutarse como root.

    -
    if os.geteuid()==0: # non-root check
    -    sys.exit(" ERROR: Do not run as root...\n")
    -else:
    -    print " You are normal user... \n"
    +
    if os.geteuid()==0: # non-root check
    +    sys.exit(" ERROR: Do not run as root...\n")
    +else:
    +    print " You are normal user... \n"
     

    Ejemplo:

    -
    juan@maverick:~$ /usr/bin/env python test.py
    -
    - You are normal user...
    -
    -juan@maverick:~$ sudo /usr/bin/env python test.py
    -
    - ERROR: Do not run as root...
    +
    juan@maverick:~$ /usr/bin/env python test.py
    +
    + You are normal user...
    +
    +juan@maverick:~$ sudo /usr/bin/env python test.py
    +
    + ERROR: Do not run as root...
     
    diff --git a/recetario/sabersinlibreriaestainstalada/index.html b/recetario/sabersinlibreriaestainstalada/index.html index 659439ee9..7f5647b22 100644 --- a/recetario/sabersinlibreriaestainstalada/index.html +++ b/recetario/sabersinlibreriaestainstalada/index.html @@ -28,7 +28,7 @@ Ejemplo: juan@maverick:~$ python -c 'import gtk'&&echo"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + @@ -87,16 +87,16 @@

    Saber Si N Libreria Esta Instalada

    Cómo saber si N librería está instalada SIN ingresar al intérprete de Python. Funciona en la Bash de Linux.

    -
    python -c 'import libreria'&&echo OK
    +
    python -c 'import libreria'&&echo OK
     

    Ejemplo:

    -
    juan@maverick:~$ python -c 'import gtk'&&echo OK
    -OK
    -juan@maverick:~$ python -c 'import libreriaquenoestainstalada'&&echo OK
    -Traceback (most recent call last):
    -  File "<string>", line 1, in <module>
    -ImportError: No module named libreriaquenoestainstalada
    -juan@maverick:~$
    +
    juan@maverick:~$ python -c 'import gtk'&&echo OK
    +OK
    +juan@maverick:~$ python -c 'import libreriaquenoestainstalada'&&echo OK
    +Traceback (most recent call last):
    +  File "<string>", line 1, in <module>
    +ImportError: No module named libreriaquenoestainstalada
    +juan@maverick:~$
     
    diff --git a/recetario/servidorcom/index.html b/recetario/servidorcom/index.html index 069c91380..bc4fdff1f 100644 --- a/recetario/servidorcom/index.html +++ b/recetario/servidorcom/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +
    @@ -94,87 +94,87 @@

    Servidor Interfase Com

  • Método Evaluar: evalua la expresión Python recibida y devuelve su resultado.

  • Archivo miservidorcom.py

    -
    # -*- coding: iso-8859-1 -*-
    -
    -import sys
    -
    -class MiMiniInterpretePython:
    -    _public_methods_ = ['Evaluar']    # Métodos a exportar por el servidor COM
    -    _public_attrs_ = ['Version']      # Atributos a exportar por el servidor COM
    -    _readonly_attrs_ = _public_attrs_ # Atributos de solo lectura
    -    _reg_progid_ = "MiMiniInterpretePython"   # Nombre para Crear el Objeto COM
    -    # NUNCA copiar el siguiente ID
    -    # Usar "print pythoncom.CreateGuid()" para crear uno nuevo
    -    _reg_clsid_ = "{ECDDA31C-2999-4C77-9778-DDF75FBF81FC}"
    -
    -    def __init__(self):
    -        # constructor, setear atributos:
    -        self.Version = sys.version
    -
    -    def Evaluar(self, expresion):
    -        "Evalua una expresión python y devuelve su resultado"
    -        return eval(expresion)
    -
    -
    -# Agregar código para que si este script es ejecutado por linea de comando,
    -# por Python.exe, se auto-registre
    -if __name__=='__main__':
    -    import win32com.server.register
    -    win32com.server.register.UseCommandLine(MiMiniInterpretePython)
    +
    # -*- coding: iso-8859-1 -*-
    +
    +import sys
    +
    +class MiMiniInterpretePython:
    +    _public_methods_ = ['Evaluar']    # Métodos a exportar por el servidor COM
    +    _public_attrs_ = ['Version']      # Atributos a exportar por el servidor COM
    +    _readonly_attrs_ = _public_attrs_ # Atributos de solo lectura
    +    _reg_progid_ = "MiMiniInterpretePython"   # Nombre para Crear el Objeto COM
    +    # NUNCA copiar el siguiente ID
    +    # Usar "print pythoncom.CreateGuid()" para crear uno nuevo
    +    _reg_clsid_ = "{ECDDA31C-2999-4C77-9778-DDF75FBF81FC}"
    +
    +    def __init__(self):
    +        # constructor, setear atributos:
    +        self.Version = sys.version
    +
    +    def Evaluar(self, expresion):
    +        "Evalua una expresión python y devuelve su resultado"
    +        return eval(expresion)
    +
    +
    +# Agregar código para que si este script es ejecutado por linea de comando,
    +# por Python.exe, se auto-registre
    +if __name__=='__main__':
    +    import win32com.server.register
    +    win32com.server.register.UseCommandLine(MiMiniInterpretePython)
     

    Para poder usarlo desde otros lenguajes, registrar el servidor COM ejecutando desde línea de comando:

    -
    python miservidorcom.py --register
    +
    python miservidorcom.py --register
     

    El siguiente ejemplo en Visual Basic (modulo1.bas) crea el objeto COM ("instanciando" MiMiniInterpretePython) y muestra el atributo (Version), y luego solicita expresiones para evaluar en python.

    Archivo modulo1.bas:

    -
    Sub Main()
    -
    -    ' Creo el objeto Python exportado por el Servidor COM:
    -    Set ObjetoPython = CreateObject("MiMiniInterpretePython")
    -
    -    ' Obtengo un atributo del objeto python:
    -    Version = ObjetoPython.Version
    -    MsgBox Version, , "Versión de Python:"
    -
    -    Do
    -        Expresion = InputBox("Ingrese una expresión python para ser evaluada", "Ejemplo COM", "1+2")
    -        If Expresion = "" Then Exit Sub
    -        ' Llamo al método del objeto python:
    -        Resultado = ObjetoPython.Evaluar(Expresion)
    -        MsgBox Resultado, , "Resultado:"
    -    Loop
    -
    -End Sub
    +
    Sub Main()
    +
    +    ' Creo el objeto Python exportado por el Servidor COM:
    +    Set ObjetoPython = CreateObject("MiMiniInterpretePython")
    +
    +    ' Obtengo un atributo del objeto python:
    +    Version = ObjetoPython.Version
    +    MsgBox Version, , "Versión de Python:"
    +
    +    Do
    +        Expresion = InputBox("Ingrese una expresión python para ser evaluada", "Ejemplo COM", "1+2")
    +        If Expresion = "" Then Exit Sub
    +        ' Llamo al método del objeto python:
    +        Resultado = ObjetoPython.Evaluar(Expresion)
    +        MsgBox Resultado, , "Resultado:"
    +    Loop
    +
    +End Sub
     

    Ejemplo en Visual Fox Pro:

    -
    * instancio el objeto python via COM:
    -ObjetoPython = CREATEOBJECT("MiMiniInterpretePython")
    -
    -* muestro el atributo versión:
    -version = ObjetoPython.Version
    -MESSAGEBOX("Versión de Python: " + version, 0)
    -
    -* muestro el resultado de evaluar una expresión llamando al método vía COM:
    -expresion = "' '.join(['hola','mundo'])"
    -resultado = ObjetoPython.Evaluar(expresion)
    -MESSAGEBOX(resultado, 0)
    +
    * instancio el objeto python via COM:
    +ObjetoPython = CREATEOBJECT("MiMiniInterpretePython")
    +
    +* muestro el atributo versión:
    +version = ObjetoPython.Version
    +MESSAGEBOX("Versión de Python: " + version, 0)
    +
    +* muestro el resultado de evaluar una expresión llamando al método vía COM:
    +expresion = "' '.join(['hola','mundo'])"
    +resultado = ObjetoPython.Evaluar(expresion)
    +MESSAGEBOX(resultado, 0)
     

    Para generar una DLL o EXE y poder distribuir el servidor com sin necesidad de tener instalado Python, usar Py2Exe con el siguiente script de directivas de instalación (ver CrearEjecutableWindows):

    -
    from distutils.core import setup
    -import py2exe
    -
    -setup( name = "MiServidorCOM",
    -    com_server = ["miservidorcom"],
    -)
    +
    from distutils.core import setup
    +import py2exe
    +
    +setup( name = "MiServidorCOM",
    +    com_server = ["miservidorcom"],
    +)
     

    Ejecutar Py2Exe para crear el EXE, DLL y demás archivos de distribución (carpeta dist):

    -
    python setup.py py2exe
    +
    python setup.py py2exe
     

    Luego, registrar el servidor COM por línea de comando:

    -
    miservidorcom.exe --register
    +
    miservidorcom.exe --register
     

    o

    -
    regsvr32 miservidorcom.dll
    +
    regsvr32 miservidorcom.dll
     

    Para Descargar Fuentes:

    Autor / Autores:

    diff --git a/recetario/simplesoapclient/index.html b/recetario/simplesoapclient/index.html index 800ee659e..9f13ec59a 100644 --- a/recetario/simplesoapclient/index.html +++ b/recetario/simplesoapclient/index.html @@ -26,7 +26,7 @@ En este ejemplo se muestra cómo utilizar servicios webs de manera simple (código usado en Factura Electronica) Utiliza SimpleXmlElement y SimpleSoapClient, manejando de manera simple el pr"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + @@ -90,17 +90,17 @@

    Simplesoapclient

    Nota: Ver otras librerías más avanzadas.

    Ejemplo: Feriados (Ministerio del Interior)

    Ver: http://www.mininterior.gov.ar/servicios/wsferiados.asp

    -
    # Demo & Test: Feriados (Ministerio del Interior):
    -from datetime import datetime, timedelta
    -client = SoapClient(
    -    location = "http://webservices.mininterior.gov.ar/Feriados/Service.svc",
    -    action = 'http://tempuri.org/IMyService/', # SOAPAction
    -    namespace = "http://tempuri.org/FeriadoDS.xsd",
    -    trace = True)
    -dt1 = datetime.today() - timedelta(days=60)
    -dt2 = datetime.today() + timedelta(days=60)
    -feriadosXML = client.FeriadosEntreFechasAsXml(dt1=dt1.isoformat(), dt2=dt2.isoformat());
    -print feriadosXML
    +
    # Demo & Test: Feriados (Ministerio del Interior):
    +from datetime import datetime, timedelta
    +client = SoapClient(
    +    location = "http://webservices.mininterior.gov.ar/Feriados/Service.svc",
    +    action = 'http://tempuri.org/IMyService/', # SOAPAction
    +    namespace = "http://tempuri.org/FeriadoDS.xsd",
    +    trace = True)
    +dt1 = datetime.today() - timedelta(days=60)
    +dt2 = datetime.today() + timedelta(days=60)
    +feriadosXML = client.FeriadosEntreFechasAsXml(dt1=dt1.isoformat(), dt2=dt2.isoformat());
    +print feriadosXML
     

    Autor / Autores:

    MarianoReingart

    diff --git a/recetario/simplexmlelement/index.html b/recetario/simplexmlelement/index.html index babff278e..5d39af067 100644 --- a/recetario/simplexmlelement/index.html +++ b/recetario/simplexmlelement/index.html @@ -28,7 +28,7 @@ class SimpleXMLElement: "Clas'> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + @@ -87,45 +87,45 @@

    Manejo Simple De Xml (Simplexmlelement)

    En este ejemplo se muestra cómo convertir un string desde y hacia un objeto simple que representa el XML (código usado en Factura Electronica)

    -
    import xml.dom.minidom
    -
    -class SimpleXMLElement:
    -    "Clase para Manejo simple de XMLs (simil PHP)"
    -    def __init__(self, text = None, element = None, document = None):
    -        if text:
    -            self.__document = xml.dom.minidom.parseString(text)
    -            self.__element = self.__document.documentElement
    -        else:
    -            self.__element = element
    -            self.__document = document
    -    def addChild(self,tag,text=None):
    -        element = self.__document.createElement(tag)
    -        if text:
    -            element.appendChild(self.__document.createTextNode(str(text)))
    -        self.__element.appendChild(element)
    -    def asXML(self,filename=None):
    -        return self.__document.toxml('utf8')
    -    def __getattr__(self,tag):
    -        try:
    -            return SimpleXMLElement(
    -                element=self.__element.getElementsByTagName(tag)[0],
    -                document=self.__document)
    -        except:
    -            raise RuntimeError("Tag not found: %s" % tag)
    -    def __getitem__(self,item):
    -        return getattr(self,item)
    -    def __contains__( self, item):
    -        return self.__element.getElementsByTagName(item)
    -    def __unicode__(self):
    -        return self.__element.childNodes[0].data
    -    def __str__(self):
    -        return self.__element.childNodes[0].data.encode("utf8","ignore")
    -    def __repr__(self):
    -        return repr(self.__str__())
    -    def __int__(self):
    -        return int(self.__str__())
    -    def __float__(self):
    -        return float(self.__str__())
    +
    import xml.dom.minidom
    +
    +class SimpleXMLElement:
    +    "Clase para Manejo simple de XMLs (simil PHP)"
    +    def __init__(self, text = None, element = None, document = None):
    +        if text:
    +            self.__document = xml.dom.minidom.parseString(text)
    +            self.__element = self.__document.documentElement
    +        else:
    +            self.__element = element
    +            self.__document = document
    +    def addChild(self,tag,text=None):
    +        element = self.__document.createElement(tag)
    +        if text:
    +            element.appendChild(self.__document.createTextNode(str(text)))
    +        self.__element.appendChild(element)
    +    def asXML(self,filename=None):
    +        return self.__document.toxml('utf8')
    +    def __getattr__(self,tag):
    +        try:
    +            return SimpleXMLElement(
    +                element=self.__element.getElementsByTagName(tag)[0],
    +                document=self.__document)
    +        except:
    +            raise RuntimeError("Tag not found: %s" % tag)
    +    def __getitem__(self,item):
    +        return getattr(self,item)
    +    def __contains__( self, item):
    +        return self.__element.getElementsByTagName(item)
    +    def __unicode__(self):
    +        return self.__element.childNodes[0].data
    +    def __str__(self):
    +        return self.__element.childNodes[0].data.encode("utf8","ignore")
    +    def __repr__(self):
    +        return repr(self.__str__())
    +    def __int__(self):
    +        return int(self.__str__())
    +    def __float__(self):
    +        return float(self.__str__())
     

    Simplemente creamos un objeto de tipo SimpleXmlElement pasandole el string y obtenemos el objeto parseado. Se puede:

      @@ -134,14 +134,14 @@

      Manejo Simple De Xml (Simplexmlelement)

    • Preguntar con in si un tag es hijo.

    • Al acceder se devuelven elementos xml, por lo que hay que convertirlos a str, int, float, etc.

    -
    >>> from simplexmlelement import SimpleXMLElement
    ->>> span = SimpleXMLElement('<span><a href="google.com">google</a><prueba><i>1</i><float>1.5</float></prueba></span>')
    ->>> print str(span.a)
    -google
    ->>> print float(span.prueba.i)
    -1
    ->>> print float(span.prueba.float)
    -1.5
    +
    >>> from simplexmlelement import SimpleXMLElement
    +>>> span = SimpleXMLElement('<span><a href="google.com">google</a><prueba><i>1</i><float>1.5</float></prueba></span>')
    +>>> print str(span.a)
    +google
    +>>> print float(span.prueba.i)
    +1
    +>>> print float(span.prueba.float)
    +1.5
     

    Faltaría:

      diff --git a/recetario/tkbuttonicon/index.html b/recetario/tkbuttonicon/index.html index 596391c82..8a8183f52 100644 --- a/recetario/tkbuttonicon/index.html +++ b/recetario/tkbuttonicon/index.html @@ -27,7 +27,7 @@ #!code python #!/us"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - +
    @@ -87,67 +87,67 @@

    Tkbuttonicon

    Crea botones con Íconos. Si es en Windows sacar el '@'+ de la ruta al ícono. Los archivos se pueden pasar a .XBM con Gimp.

    Ideal para crear mini-toolbars con íconos personalizados.

    -
    #!code python
    -#!/usr/bin/env python
    -#-*- coding:utf-8 -*-
    -
    -from Tkinter import *
    -root = Tk()
    -#
    -boton1 = Button(root, bitmap='error')
    -boton1.pack()
    -boton2 = Button(root, bitmap='hourglass')
    -boton2.pack()
    -boton3 = Button(root, bitmap='info')
    -boton3.pack()
    -boton4 = Button(root, bitmap='questhead')
    -boton4.pack()
    -boton5 = Button(root, bitmap='warning')
    -boton5.pack()
    -boton6 = Button(root, bitmap='question')
    -boton6.pack()
    -boton7 = Button(root, bitmap='gray75')
    -boton7.pack()
    -boton8 = Button(root, bitmap='gray50')
    -boton8.pack()
    -boton9 = Button(root, bitmap='gray25')
    -boton9.pack()
    -boton10 = Button(root, bitmap='gray12')
    -boton10.pack()
    -boton11 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/icon'), state=DISABLED)
    -boton11.pack()
    -boton12 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/calculator'), cursor='hand2')
    -boton12.pack()
    -boton13 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/boxes'), relief=FLAT)
    -boton13.pack()
    -boton14 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/noletters'), bg='green')
    -boton14.pack()
    -boton15 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/dot'), bg='red')
    -boton15.pack()
    -boton16 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/Down'), bg='blue')
    -boton16.pack()
    -boton17 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/flagdown'), fg='green')
    -boton17.pack()
    -boton18 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/mailfull'), fg='red')
    -boton18.pack()
    -boton19 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/opendot'), fg='blue')
    -boton19.pack()
    -boton20 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/stipple'), bg='black', fg='grey')
    -boton20.pack()
    -boton21 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/target'), highlightcolor='red')
    -boton21.pack()
    -boton22 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/terminal'))
    -boton22.pack()
    -boton23 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/letters'))
    -boton23.pack()
    -boton24 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/tie_fighter'))
    -boton24.pack()
    -boton25 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/woman'), bg='pink')
    -boton25.pack()
    -# botonX = Button(root, bitmap=('@'+'/path/to/your/custom/icon.xbm'), bg='someColor', fg='AnotherColor')
    -# botonX.pack()
    -#
    -root.mainloop()
    +
    #!code python
    +#!/usr/bin/env python
    +#-*- coding:utf-8 -*-
    +
    +from Tkinter import *
    +root = Tk()
    +#
    +boton1 = Button(root, bitmap='error')
    +boton1.pack()
    +boton2 = Button(root, bitmap='hourglass')
    +boton2.pack()
    +boton3 = Button(root, bitmap='info')
    +boton3.pack()
    +boton4 = Button(root, bitmap='questhead')
    +boton4.pack()
    +boton5 = Button(root, bitmap='warning')
    +boton5.pack()
    +boton6 = Button(root, bitmap='question')
    +boton6.pack()
    +boton7 = Button(root, bitmap='gray75')
    +boton7.pack()
    +boton8 = Button(root, bitmap='gray50')
    +boton8.pack()
    +boton9 = Button(root, bitmap='gray25')
    +boton9.pack()
    +boton10 = Button(root, bitmap='gray12')
    +boton10.pack()
    +boton11 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/icon'), state=DISABLED)
    +boton11.pack()
    +boton12 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/calculator'), cursor='hand2')
    +boton12.pack()
    +boton13 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/boxes'), relief=FLAT)
    +boton13.pack()
    +boton14 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/noletters'), bg='green')
    +boton14.pack()
    +boton15 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/dot'), bg='red')
    +boton15.pack()
    +boton16 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/Down'), bg='blue')
    +boton16.pack()
    +boton17 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/flagdown'), fg='green')
    +boton17.pack()
    +boton18 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/mailfull'), fg='red')
    +boton18.pack()
    +boton19 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/opendot'), fg='blue')
    +boton19.pack()
    +boton20 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/stipple'), bg='black', fg='grey')
    +boton20.pack()
    +boton21 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/target'), highlightcolor='red')
    +boton21.pack()
    +boton22 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/terminal'))
    +boton22.pack()
    +boton23 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/letters'))
    +boton23.pack()
    +boton24 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/tie_fighter'))
    +boton24.pack()
    +boton25 = Button(root, bitmap=('@'+'/usr/include/X11/bitmaps/woman'), bg='pink')
    +boton25.pack()
    +# botonX = Button(root, bitmap=('@'+'/path/to/your/custom/icon.xbm'), bg='someColor', fg='AnotherColor')
    +# botonX.pack()
    +#
    +root.mainloop()
     
    diff --git a/recetario/tkonlineofflineicon/index.html b/recetario/tkonlineofflineicon/index.html index 630af03bf..0886aaff3 100644 --- a/recetario/tkonlineofflineicon/index.html +++ b/recetario/tkonlineofflineicon/index.html @@ -26,7 +26,7 @@ #!/usr/bin/env python #-*- "> - + Ir al contenido principal @@ -60,12 +60,12 @@ - +
    @@ -85,30 +85,30 @@

    Tkonlineofflineicon

    Crea un ícono que cambia de estado según si se esta o no conectado a Internet. Notar que se pueden cambiar más propiedades del botón que las que este simple ejemplo cambia.

    -
    #!/usr/bin/env python
    -#-*- coding:utf-8 -*-
    -
    -from Tkinter import *
    -import socket
    -root = Tk()
    -# Comprobador de conexion a Internet
    -inet = Button(root, bitmap='info', fg='green', bg='white')
    -inet.pack(pady=20, padx=20)
    -#
    -try:
    -    socket.gethostbyname('google.com')
    -    c = socket.create_connection(('google.com', 80), 1)
    -    m = socket.gethostbyname('google.com')
    -    print m  # imprime la ip de google.com para pruebas
    -    c.close()
    -except socket.gaierror:
    -    print (" ERROR: DNS Error... ")
    -    inet.config(bitmap='error', fg='red', bg='black') # cambia a un icono de error
    -except socket.error:
    -    print (" ERROR: Connection error... ")
    -    inet.config(bitmap='error', fg='red', bg='black') # cambia a un icono de error
    -#
    -root.mainloop()
    +
    #!/usr/bin/env python
    +#-*- coding:utf-8 -*-
    +
    +from Tkinter import *
    +import socket
    +root = Tk()
    +# Comprobador de conexion a Internet
    +inet = Button(root, bitmap='info', fg='green', bg='white')
    +inet.pack(pady=20, padx=20)
    +#
    +try:
    +    socket.gethostbyname('google.com')
    +    c = socket.create_connection(('google.com', 80), 1)
    +    m = socket.gethostbyname('google.com')
    +    print m  # imprime la ip de google.com para pruebas
    +    c.close()
    +except socket.gaierror:
    +    print (" ERROR: DNS Error... ")
    +    inet.config(bitmap='error', fg='red', bg='black') # cambia a un icono de error
    +except socket.error:
    +    print (" ERROR: Connection error... ")
    +    inet.config(bitmap='error', fg='red', bg='black') # cambia a un icono de error
    +#
    +root.mainloop()
     
    diff --git a/recetario/tkscrollwhell/index.html b/recetario/tkscrollwhell/index.html index 72bc61bd7..0c25b0f98 100644 --- a/recetario/tkscrollwhell/index.html +++ b/recetario/tkscrollwhell/index.html @@ -30,7 +30,7 @@ root = Tk() label = La"> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + @@ -89,28 +89,28 @@

    Tkscrollwhell

    Usando la rueda de Scroll del ratón con TK. Ejemplo simple con un poco de imaginación puede manejar más cosas.

    -
    #!/usr/bin/env python
    -#-*- coding:utf-8 -*-
    -
    -from Tkinter import *
    -root = Tk()
    -label = Label(root, text='Elija su Sexo usando la Rueda Scroll del Raton:')
    -label.pack()
    -optionlist = ("Femenino", "Masculino")
    -var = StringVar()
    -var.set(optionlist[0])
    -optmen = OptionMenu(root, var, "Femenino", "Masculino")
    -#
    -def mouse_wheel(event):  # responde a la rueda de scroll
    -        if event.num == 5 or event.delta == -120:
    -            var.set(optionlist[0])
    -        if event.num == 4 or event.delta == 120:
    -            var.set(optionlist[1])
    -#
    -optmen.bind("<Button-4>", mouse_wheel)
    -optmen.bind("<Button-5>", mouse_wheel)
    -optmen.pack()
    -root.mainloop()
    +
    #!/usr/bin/env python
    +#-*- coding:utf-8 -*-
    +
    +from Tkinter import *
    +root = Tk()
    +label = Label(root, text='Elija su Sexo usando la Rueda Scroll del Raton:')
    +label.pack()
    +optionlist = ("Femenino", "Masculino")
    +var = StringVar()
    +var.set(optionlist[0])
    +optmen = OptionMenu(root, var, "Femenino", "Masculino")
    +#
    +def mouse_wheel(event):  # responde a la rueda de scroll
    +        if event.num == 5 or event.delta == -120:
    +            var.set(optionlist[0])
    +        if event.num == 4 or event.delta == 120:
    +            var.set(optionlist[1])
    +#
    +optmen.bind("<Button-4>", mouse_wheel)
    +optmen.bind("<Button-5>", mouse_wheel)
    +optmen.pack()
    +root.mainloop()
     
    diff --git a/recetario/tkversionprint/index.html b/recetario/tkversionprint/index.html index 4d8dc34f3..874e1f8f5 100644 --- a/recetario/tkversionprint/index.html +++ b/recetario/tkversionprint/index.html @@ -34,7 +34,7 @@ Ejemplo: jua"> - + Ir al contenido principal @@ -68,12 +68,12 @@ - + @@ -93,17 +93,17 @@

    Tkversionprint

    Imprime la versión de TK que se está usando actualmente.

    -
    from Tkinter import *
    -root = Tk()
    -#
    -tkversion = root.tk.eval('info patchlevel')
    -print 'TK Version = '+tkversion
    -#
    -root.mainloop()
    +
    from Tkinter import *
    +root = Tk()
    +#
    +tkversion = root.tk.eval('info patchlevel')
    +print 'TK Version = '+tkversion
    +#
    +root.mainloop()
     

    Ejemplo:

    -
    juan@maverick:~$ /usr/bin/env python test.py
    -TK Version = 8.5.8
    +
    juan@maverick:~$ /usr/bin/env python test.py
    +TK Version = 8.5.8
     
    diff --git a/recetario/tkwindowicon/index.html b/recetario/tkwindowicon/index.html index 48be1603c..ba359fda3 100644 --- a/recetario/tkwindowicon/index.html +++ b/recetario/tkwindowicon/index.html @@ -32,7 +32,7 @@ try: root.wm_iconbitmap('@'+'/"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - +
    @@ -91,37 +91,37 @@

    Tkwindowicon

    Crea una ventana con Ícono de ventana. Los archivos se pueden pasar a .XBM con Gimp.

    -
    #!/usr/bin/env python
    -#-*- coding:utf-8 -*-
    -
    -from Tkinter import *
    -root = Tk()
    -#
    -try:
    -    root.wm_iconbitmap('@'+'/usr/include/X11/bitmaps/icon')  # Ruta al icono, formato .XBM
    -except TclError:
    -    print(" ")
    -    print(" ERROR: Icon File not found... ") # imprime este mensaje si el icono no se encuentra
    -    print(" ")
    -    pass
    -#
    -root.mainloop()
    +
    #!/usr/bin/env python
    +#-*- coding:utf-8 -*-
    +
    +from Tkinter import *
    +root = Tk()
    +#
    +try:
    +    root.wm_iconbitmap('@'+'/usr/include/X11/bitmaps/icon')  # Ruta al icono, formato .XBM
    +except TclError:
    +    print(" ")
    +    print(" ERROR: Icon File not found... ") # imprime este mensaje si el icono no se encuentra
    +    print(" ")
    +    pass
    +#
    +root.mainloop()
     

    Si estamos en Windows es mejor usar la función iconbitmap('Icono.ico') que también se puede pasar la imagen a .ico con Gimp.

    -
    #!/usr/bin/python
    -# -*- coding: utf-8 -*-
    -from Tkinter import *
    -root = Tk()
    -#
    -try:
    -    root.iconbitmap('Icono.ico')  # icono en  formato .ico de windows
    -except TclError:
    -    print(" ")
    -    print(" ERROR: Icon File not found... ") # imprime este mensaje si el icono no se encuentra
    -    print(" ")
    -    pass
    -#
    -root.mainloop()
    +
    #!/usr/bin/python
    +# -*- coding: utf-8 -*-
    +from Tkinter import *
    +root = Tk()
    +#
    +try:
    +    root.iconbitmap('Icono.ico')  # icono en  formato .ico de windows
    +except TclError:
    +    print(" ")
    +    print(" ERROR: Icon File not found... ") # imprime este mensaje si el icono no se encuentra
    +    print(" ")
    +    pass
    +#
    +root.mainloop()
     
    diff --git a/recetario/tkwizards/index.html b/recetario/tkwizards/index.html index f0efd9cb4..4b2792207 100644 --- a/recetario/tkwizards/index.html +++ b/recetario/tkwizards/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +
    @@ -87,94 +87,94 @@

    Tk Wizards

    Sacando todo el código necesario para generar el Wizard en sí mismo, agregar nuevas páginas es simple.

    Las páginas pueden contener cualquier widget, en este ejemplo solo se usa 1 label por cada una.

    Screenshot:

    -/images/TKWizards/temp.jpg
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -try:
    -    import Tkinter as tk  # Python2
    -except ImportError:
    -    import tkinter as tk  # Python3
    -
    -class Wizard(tk.Toplevel):
    -    def __init__(self, npages, master=None):
    -        self.master = master
    -        self.pages = []
    -        self.current = 0
    -        tk.Toplevel.__init__(self)
    -        #self.overrideredirect() # saca el decorador de ventana
    -        self.protocol("WM_DELETE_WINDOW", self.onQuit)
    -        #self.attributes('-toolwindow', True) # ToolWindowz
    -        self.attributes('-topmost', True)
    -        if master:
    -            self.transient(self.master)
    -            self.lift(master)
    -        for page in range(npages):
    -            self.pages.append(tk.Frame(self))
    -        self.pages[0].pack(fill='both', expand=1)
    -        self.__wizard_buttons()
    -
    -    def onQuit(self):
    -        pass # hace algo on quit
    -
    -    def __wizard_buttons(self):
    -        for indx, frm in enumerate(self.pages):
    -            btnframe = tk.Frame(frm, bd=1, bg='#3C3B37')
    -            btnframe.pack(side='bottom', fill='x')
    -            nextbtn = tk.Button(btnframe, bd=0, bg='#F2F1F0', activebackground='#F58151', highlightcolor='red', cursor='hand2', text="Siguiente >>", width=10, command=self.__next_page)
    -            nextbtn.pack(side='right', anchor='e', padx=5, pady=5)
    -            if indx != 0:
    -                prevbtn = tk.Button(btnframe, bd=0, bg='#F2F1F0', activebackground='#F58151', highlightcolor='red', cursor='hand2', text="<< Atras", width=10, command=self.__prev_page)
    -                prevbtn.pack(side='right', anchor='e', padx=5, pady=5)
    -                if indx == len(self.pages) - 1:
    -                    nextbtn.configure(text="Terminar", bd=0, bg='#F2F1F0', activebackground='#F58151', highlightcolor='red', cursor='hand2', command=self.close)
    -
    -    def __next_page(self):
    -        if self.current == len(self.pages):
    -            return
    -        self.pages[self.current].pack_forget()
    -        self.current += 1
    -        self.pages[self.current].pack(fill='both', expand=1)
    -
    -    def __prev_page(self):
    -        if self.current == 0:
    -            return
    -        self.pages[self.current].pack_forget()
    -        self.current -= 1
    -        self.pages[self.current].pack(fill='both', expand=1)
    -
    -    def add_page_body(self, body):
    -        body.pack(side='top', fill='both', padx=6, pady=12)
    -
    -    def page(self, page_num):
    -        try:
    -            page = self.pages[page_num]
    -        except KeyError("Pagina Invalida! : %s" % page_num):
    -            return 0
    -        return page
    -
    -    def close(self):
    -        if self.validate():
    -            self.master.iconify()
    -            print (' TK Wizard finished... ')
    -            self.destroy()
    -            self.master.destroy() # remover?
    -
    -    def validate(self):
    -        return 1 # hace algo
    -
    -if __name__ == "__main__":
    -    root = tk.Tk()
    -    root.title(' TK Wizards ')
    -    root.focus()
    -    wizard = Wizard(npages=3, master=root)
    -    wizard.minsize(400, 350)
    -    page0 = tk.Label(wizard.page(0), text='Pagina 1: ...Bienvenido al Wizard de TK !')
    -    page1 = tk.Label(wizard.page(1), text='Pagina 2: Acepta las condiciones de la WTFPL ?')
    -    page2 = tk.Label(wizard.page(2), text='Pagina 3: Felicitaciones, nada no se ha instalado correctamente.')
    -    wizard.add_page_body(page0)
    -    wizard.add_page_body(page1)
    -    wizard.add_page_body(page2)
    -    root.mainloop()
    +/images/TKWizards/temp.jpg
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +try:
    +    import Tkinter as tk  # Python2
    +except ImportError:
    +    import tkinter as tk  # Python3
    +
    +class Wizard(tk.Toplevel):
    +    def __init__(self, npages, master=None):
    +        self.master = master
    +        self.pages = []
    +        self.current = 0
    +        tk.Toplevel.__init__(self)
    +        #self.overrideredirect() # saca el decorador de ventana
    +        self.protocol("WM_DELETE_WINDOW", self.onQuit)
    +        #self.attributes('-toolwindow', True) # ToolWindowz
    +        self.attributes('-topmost', True)
    +        if master:
    +            self.transient(self.master)
    +            self.lift(master)
    +        for page in range(npages):
    +            self.pages.append(tk.Frame(self))
    +        self.pages[0].pack(fill='both', expand=1)
    +        self.__wizard_buttons()
    +
    +    def onQuit(self):
    +        pass # hace algo on quit
    +
    +    def __wizard_buttons(self):
    +        for indx, frm in enumerate(self.pages):
    +            btnframe = tk.Frame(frm, bd=1, bg='#3C3B37')
    +            btnframe.pack(side='bottom', fill='x')
    +            nextbtn = tk.Button(btnframe, bd=0, bg='#F2F1F0', activebackground='#F58151', highlightcolor='red', cursor='hand2', text="Siguiente >>", width=10, command=self.__next_page)
    +            nextbtn.pack(side='right', anchor='e', padx=5, pady=5)
    +            if indx != 0:
    +                prevbtn = tk.Button(btnframe, bd=0, bg='#F2F1F0', activebackground='#F58151', highlightcolor='red', cursor='hand2', text="<< Atras", width=10, command=self.__prev_page)
    +                prevbtn.pack(side='right', anchor='e', padx=5, pady=5)
    +                if indx == len(self.pages) - 1:
    +                    nextbtn.configure(text="Terminar", bd=0, bg='#F2F1F0', activebackground='#F58151', highlightcolor='red', cursor='hand2', command=self.close)
    +
    +    def __next_page(self):
    +        if self.current == len(self.pages):
    +            return
    +        self.pages[self.current].pack_forget()
    +        self.current += 1
    +        self.pages[self.current].pack(fill='both', expand=1)
    +
    +    def __prev_page(self):
    +        if self.current == 0:
    +            return
    +        self.pages[self.current].pack_forget()
    +        self.current -= 1
    +        self.pages[self.current].pack(fill='both', expand=1)
    +
    +    def add_page_body(self, body):
    +        body.pack(side='top', fill='both', padx=6, pady=12)
    +
    +    def page(self, page_num):
    +        try:
    +            page = self.pages[page_num]
    +        except KeyError("Pagina Invalida! : %s" % page_num):
    +            return 0
    +        return page
    +
    +    def close(self):
    +        if self.validate():
    +            self.master.iconify()
    +            print (' TK Wizard finished... ')
    +            self.destroy()
    +            self.master.destroy() # remover?
    +
    +    def validate(self):
    +        return 1 # hace algo
    +
    +if __name__ == "__main__":
    +    root = tk.Tk()
    +    root.title(' TK Wizards ')
    +    root.focus()
    +    wizard = Wizard(npages=3, master=root)
    +    wizard.minsize(400, 350)
    +    page0 = tk.Label(wizard.page(0), text='Pagina 1: ...Bienvenido al Wizard de TK !')
    +    page1 = tk.Label(wizard.page(1), text='Pagina 2: Acepta las condiciones de la WTFPL ?')
    +    page2 = tk.Label(wizard.page(2), text='Pagina 3: Felicitaciones, nada no se ha instalado correctamente.')
    +    wizard.add_page_body(page0)
    +    wizard.add_page_body(page1)
    +    wizard.add_page_body(page2)
    +    root.mainloop()
     
    diff --git a/recetario/ttkholamundo/index.html b/recetario/ttkholamundo/index.html index eb88f3c80..f85ef4b31 100644 --- a/recetario/ttkholamundo/index.html +++ b/recetario/ttkholamundo/index.html @@ -33,7 +33,7 @@ class HolaMundoApp(ttk.Frame): '''Clase qu"> - + Ir al contenido principal @@ -67,12 +67,12 @@ - + @@ -92,34 +92,34 @@

    Ttkholamundo

    Crea una ventana que muestra el famoso mensaje "Hola mundo".

    -/images/ttkHolamundo/ttkHolamundo.png
    #!/usr/bin/env python3
    -#-*- coding:utf-8 -*-
    -
    -import tkinter as tk
    -from tkinter import ttk
    -
    -class HolaMundoApp(ttk.Frame):
    -    '''Clase que define una ventana que muestra el "Hola mundo"'''
    -
    -    def __init__(self, master=None):
    -        ttk.Frame.__init__(self, master)
    -
    -        #Creamos un label
    -        o = ttk.Label(self, text='Hola PyAr!', anchor='center')
    -        #Lo agregamos a la ventana.
    -        o.pack(fill='both', expand=True)
    -        #Agregamos este frame a la ventana principal (Top level window)
    -        self.pack(fill='both', expand=True)
    -
    -        #Configuramos la ventana principal
    -        top = self.winfo_toplevel()
    -        top.title('Hola mundo')
    -        top.minsize(width=300, height=200)
    -
    -
    -if __name__ == '__main__':
    -    app = HolaMundoApp()
    -    app.mainloop()
    +/images/ttkHolamundo/ttkHolamundo.png
    #!/usr/bin/env python3
    +#-*- coding:utf-8 -*-
    +
    +import tkinter as tk
    +from tkinter import ttk
    +
    +class HolaMundoApp(ttk.Frame):
    +    '''Clase que define una ventana que muestra el "Hola mundo"'''
    +
    +    def __init__(self, master=None):
    +        ttk.Frame.__init__(self, master)
    +
    +        #Creamos un label
    +        o = ttk.Label(self, text='Hola PyAr!', anchor='center')
    +        #Lo agregamos a la ventana.
    +        o.pack(fill='both', expand=True)
    +        #Agregamos este frame a la ventana principal (Top level window)
    +        self.pack(fill='both', expand=True)
    +
    +        #Configuramos la ventana principal
    +        top = self.winfo_toplevel()
    +        top.title('Hola mundo')
    +        top.minsize(width=300, height=200)
    +
    +
    +if __name__ == '__main__':
    +    app = HolaMundoApp()
    +    app.mainloop()
     
    diff --git a/recetario/validarcuit/index.html b/recetario/validarcuit/index.html index bd0527bc5..3444600bf 100644 --- a/recetario/validarcuit/index.html +++ b/recetario/validarcuit/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -89,34 +89,34 @@

    Validar Cuit

    Aclaración: que el CUIT sea válido no quiere decir que la persona titular exista y esté habilitada por los organismos correspondientes.

    Siempre se debe verificar la vigencia del CUIT en la página de la AFIP (Administración Federal de Ingresos Públicos). Por el momento es una página web, quizas en un futuro ofrezcan un servicio web para automatizar el proceso. Tambien es posible bajarse un padrón (archivo de texto plano), tarea para otra receta 🙂

    Ejemplos:

    -
    >>> validar_cuit("00-00000000-0")
    -True
    ->>> validar_cuit("00-00000000-1")
    -False
    +
    >>> validar_cuit("00-00000000-0")
    +True
    +>>> validar_cuit("00-00000000-1")
    +False
     

    Código:

    -
    def validar_cuit(cuit):
    -    # validaciones minimas
    -    if len(cuit) != 13 or cuit[2] != "-" or cuit[11] != "-":
    -        return False
    -
    -    base = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
    -
    -    cuit = cuit.replace("-", "") # remuevo las barras
    -
    -    # calculo el digito verificador:
    -    aux = 0
    -    for i in xrange(10):
    -        aux += int(cuit[i]) * base[i]
    -
    -    aux = 11 - (aux - (int(aux / 11) * 11))
    -
    -    if aux == 11:
    -        aux = 0
    -    if aux == 10:
    -        aux = 9
    -
    -    return aux == int(cuit[10])
    +
    def validar_cuit(cuit):
    +    # validaciones minimas
    +    if len(cuit) != 13 or cuit[2] != "-" or cuit[11] != "-":
    +        return False
    +
    +    base = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
    +
    +    cuit = cuit.replace("-", "") # remuevo las barras
    +
    +    # calculo el digito verificador:
    +    aux = 0
    +    for i in xrange(10):
    +        aux += int(cuit[i]) * base[i]
    +
    +    aux = 11 - (aux - (int(aux / 11) * 11))
    +
    +    if aux == 11:
    +        aux = 0
    +    if aux == 10:
    +        aux = 9
    +
    +    return aux == int(cuit[10])
     

    Autor / Autores:

    MarianoReingart

    diff --git a/recetario/ventanapasswordvibra/index.html b/recetario/ventanapasswordvibra/index.html index f81050c76..ad336fc50 100644 --- a/recetario/ventanapasswordvibra/index.html +++ b/recetario/ventanapasswordvibra/index.html @@ -29,7 +29,7 @@ #!/usr/bin/env python # -*- co"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + @@ -91,52 +91,52 @@

    Ventana De Password Que Vibra

  • Crear una ventana para passwords que vibra si la password es incorrecta. El campo de texto oculta los caracteres en pantalla. La vibración es configurable.

  • Screenshot:

    -/images/VentanaPasswordVibra/temp.jpg
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -#
    -from Tkinter import *
    -from time import sleep
    -from random import randint
    -#
    -# correct password is: password
    -#
    -def check(Event = None):
    -    if hash(var.get()) != -1767432613:  # hash for password
    -        o = root.geometry()
    -        l['text'] = 'Wrong Password:\nAttemp will be logged and reported.'
    -        l.config(fg='red')
    -        for times in range(50):
    -                 root.geometry("+%d+%d" %(int(root.geometry().split("+")[1])+randint(-69, 69), int(root.geometry().split("+")[2])+randint(-69, 69)))
    -                 root.update()
    -                 sleep(.05)
    -                 root.geometry(o)
    -        root.geometry(o)
    -        root.update()
    -    else:
    -        l['text'] = 'OK: Connected to FBI Main Server...'
    -        print ('\nConnected to FBI Main Server...\n')
    -        l.config(fg='black')
    -        root.iconify()
    -        sleep(.25)
    -        root.deiconify()
    -        root.geometry()
    -    var.set("")
    -#
    -root = Tk()
    -root.resizable(0, 0)
    -root.title("FBI VPN Client")
    -root.geometry("+800+350")
    -root.wm_attributes("-topmost", 1)
    -root.focus()
    -root.config(bg='#F2F1F0', cursor='hand2')
    -var = StringVar()
    -l = Label(root, text = "FBI Login: Please type your password...", font=('ubuntu', 10), bg='#F2F1F0', bd=0, relief='flat', cursor='hand2')
    -l.grid()
    -a = Entry(root, font=('ubuntu', 12, 'bold'), show = '●', bg='#D7DAED', bd=0, relief='flat', cursor='xterm', highlightcolor='red', textvariable = var)  # show = '*'
    -a.grid(row = 1, column = 0, padx = 10, pady = 10)
    -a.bind("<Return>", check)
    -a.focus()
    -root.mainloop()
    +/images/VentanaPasswordVibra/temp.jpg
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +#
    +from Tkinter import *
    +from time import sleep
    +from random import randint
    +#
    +# correct password is: password
    +#
    +def check(Event = None):
    +    if hash(var.get()) != -1767432613:  # hash for password
    +        o = root.geometry()
    +        l['text'] = 'Wrong Password:\nAttemp will be logged and reported.'
    +        l.config(fg='red')
    +        for times in range(50):
    +                 root.geometry("+%d+%d" %(int(root.geometry().split("+")[1])+randint(-69, 69), int(root.geometry().split("+")[2])+randint(-69, 69)))
    +                 root.update()
    +                 sleep(.05)
    +                 root.geometry(o)
    +        root.geometry(o)
    +        root.update()
    +    else:
    +        l['text'] = 'OK: Connected to FBI Main Server...'
    +        print ('\nConnected to FBI Main Server...\n')
    +        l.config(fg='black')
    +        root.iconify()
    +        sleep(.25)
    +        root.deiconify()
    +        root.geometry()
    +    var.set("")
    +#
    +root = Tk()
    +root.resizable(0, 0)
    +root.title("FBI VPN Client")
    +root.geometry("+800+350")
    +root.wm_attributes("-topmost", 1)
    +root.focus()
    +root.config(bg='#F2F1F0', cursor='hand2')
    +var = StringVar()
    +l = Label(root, text = "FBI Login: Please type your password...", font=('ubuntu', 10), bg='#F2F1F0', bd=0, relief='flat', cursor='hand2')
    +l.grid()
    +a = Entry(root, font=('ubuntu', 12, 'bold'), show = '●', bg='#D7DAED', bd=0, relief='flat', cursor='xterm', highlightcolor='red', textvariable = var)  # show = '*'
    +a.grid(row = 1, column = 0, padx = 10, pady = 10)
    +a.bind("<Return>", check)
    +a.focus()
    +root.mainloop()
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    diff --git a/recetario/winbatt/index.html b/recetario/winbatt/index.html index bc06c7a48..696ab59f2 100644 --- a/recetario/winbatt/index.html +++ b/recetario/winbatt/index.html @@ -26,7 +26,7 @@ Esta receta es un ejemplo de cómo utilizar funciones nativas de las bibliotecas de Windows desde Python (usando ctypes). Por ejemplo, en este caso se usa para consultar el estado de la bat"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + @@ -99,51 +99,51 @@

    Winbatt (Ctypes + Powrprof.dll En Win)

  • imprime los resultados

  • Archivo winbatt.py

    -
    # -*- coding: iso-8859-1 -*-
    -
    -import ctypes
    -
    -l = ctypes.cdll.LoadLibrary("powrprof")
    -
    -SystemBatteryState = 5  # POWER_INFORMATION_LEVEL enum
    -
    -class SYSTEM_BATTERY_STATE(ctypes.Structure):
    -    _fields_ = [
    -                ("AcOnLine", ctypes.c_bool),
    -                ("BatteryPresent", ctypes.c_bool),
    -                ("Charging", ctypes.c_bool),
    -                ("Discharging", ctypes.c_bool),
    -                ("Spare1", ctypes.c_bool * 4),
    -                ("MaxCapacity", ctypes.c_long),
    -                ("RemainingCapacity", ctypes.c_long),
    -                ("Rate", ctypes.c_long),
    -                ("EstimatedTime", ctypes.c_long),
    -                ("DefaultAlert1", ctypes.c_long),
    -                ("DefaultAlert2", ctypes.c_long),
    -                ]
    -
    -
    -sb = SYSTEM_BATTERY_STATE(0)
    -retval = l.CallNtPowerInformation(SystemBatteryState,
    -                                  None, 0,
    -                                  ctypes.addressof(sb), ctypes.sizeof(sb))
    -assert retval == 0  # debe devolver 0 si no hay error
    -print "AcOnLine:", sb.AcOnLine
    -print "Charging:", sb.Charging
    -print "Discharging:", sb.Discharging
    -print "Capacity:", sb.MaxCapacity, "mWh max", sb.RemainingCapacity, "mWh remaining",
    -print sb.RemainingCapacity*100/sb.MaxCapacity, "%"
    -print "Rate:", sb.Rate / 1000.0, "W"
    -print "Estimated Time:", sb.EstimatedTime / 3600, "h", sb.EstimatedTime / 60 % 60, "min"
    +
    # -*- coding: iso-8859-1 -*-
    +
    +import ctypes
    +
    +l = ctypes.cdll.LoadLibrary("powrprof")
    +
    +SystemBatteryState = 5  # POWER_INFORMATION_LEVEL enum
    +
    +class SYSTEM_BATTERY_STATE(ctypes.Structure):
    +    _fields_ = [
    +                ("AcOnLine", ctypes.c_bool),
    +                ("BatteryPresent", ctypes.c_bool),
    +                ("Charging", ctypes.c_bool),
    +                ("Discharging", ctypes.c_bool),
    +                ("Spare1", ctypes.c_bool * 4),
    +                ("MaxCapacity", ctypes.c_long),
    +                ("RemainingCapacity", ctypes.c_long),
    +                ("Rate", ctypes.c_long),
    +                ("EstimatedTime", ctypes.c_long),
    +                ("DefaultAlert1", ctypes.c_long),
    +                ("DefaultAlert2", ctypes.c_long),
    +                ]
    +
    +
    +sb = SYSTEM_BATTERY_STATE(0)
    +retval = l.CallNtPowerInformation(SystemBatteryState,
    +                                  None, 0,
    +                                  ctypes.addressof(sb), ctypes.sizeof(sb))
    +assert retval == 0  # debe devolver 0 si no hay error
    +print "AcOnLine:", sb.AcOnLine
    +print "Charging:", sb.Charging
    +print "Discharging:", sb.Discharging
    +print "Capacity:", sb.MaxCapacity, "mWh max", sb.RemainingCapacity, "mWh remaining",
    +print sb.RemainingCapacity*100/sb.MaxCapacity, "%"
    +print "Rate:", sb.Rate / 1000.0, "W"
    +print "Estimated Time:", sb.EstimatedTime / 3600, "h", sb.EstimatedTime / 60 % 60, "min"
     

    Para usarlo se puede ejecutar desde línea de comando:

    -
    C:\src>python winbatt.py
    -AcOnLine: False
    -Charging: False
    -Discharging: True
    -Capacity: 45140 mWh max 5417 mWh remaining 12 %
    -Rate: -9.435 W
    -Estimated Time: 0 h 34 min
    +
    C:\src>python winbatt.py
    +AcOnLine: False
    +Charging: False
    +Discharging: True
    +Capacity: 45140 mWh max 5417 mWh remaining 12 %
    +Rate: -9.435 W
    +Estimated Time: 0 h 34 min
     

    Para Descargar Fuentes:

    Autor / Autores:

    diff --git a/recetario/xdg-sudo/index.html b/recetario/xdg-sudo/index.html index 97a236af2..ef23757f7 100644 --- a/recetario/xdg-sudo/index.html +++ b/recetario/xdg-sudo/index.html @@ -28,7 +28,7 @@ # Licence: GPLv3 # xdg-sudo: Automatically choose "> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + @@ -87,49 +87,49 @@

    Xdg-Sudo

    El sudo gráfico universal para escritorios GTK/QT/loquesea, inspirado en el funcionamiento de xdg-open.

    -
    #!/usr/bin/env python
    -# -*- coding: utf-8 -*-
    -# Licence: GPLv3
    -# xdg-sudo: Automatically choose "gksudo" or "kdesudo"
    -import os
    -import sys
    -#import antigravity
    -import subprocess
    -import re
    -if os.geteuid()==0: # non-root check, because if you are root, all this is pointless
    -    sys.exit(" ERROR: Do not run as root...\n")
    -else:
    -    print (" You are normal user... \n")
    -# Prepare actual command to execute
    -parameters = " ".join([re.escape(a) for a in sys.argv[1:]])
    -# Test which tools exist
    -kdesudo = os.path.exists('/usr/bin/kdesudo')
    -gtksudo = os.path.exists('/usr/bin/gksudo')
    -# If we have at least one of them, check which one to use.
    -if kdesudo or gtksudo:
    -    if kdesudo and gtksudo:
    -        # Test if gnome runs
    -        process = subprocess.Popen("ps -ae | grep gnome-session", shell=True, stdout=subprocess.PIPE)
    -        process.wait()
    -        if len(process.communicate()[0])>0:
    -            useGnome = True
    -        else:
    -            useGnome = False
    -    elif kdesudo and (not gtksudo):
    -        useGnome = False
    -    elif (not kdesudo) and gtksudo:
    -        useGnome = True
    -    # really run it
    -    if useGnome:
    -        cmd = "gksudo "
    -    else:
    -        cmd = "kdesudo "
    -    # Run the actual program now
    -    os.system(cmd+parameters)
    -else:
    -    # we dont have gksudo or kdesudo, OMFG!
    -    cmd = "xterm -e \"echo 'Neither \\\"gksudo\\\" nor \\\"kdesudo\\\" have been found on your machine. Thus, \\\"sudo\\\" is being used. Please leave this window open until the program has finished. Your are asked for your password below.'; sudo "+parameters+"; sleep 1\""
    -    os.system(cmd)
    +
    #!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +# Licence: GPLv3
    +# xdg-sudo: Automatically choose "gksudo" or "kdesudo"
    +import os
    +import sys
    +#import antigravity
    +import subprocess
    +import re
    +if os.geteuid()==0: # non-root check, because if you are root, all this is pointless
    +    sys.exit(" ERROR: Do not run as root...\n")
    +else:
    +    print (" You are normal user... \n")
    +# Prepare actual command to execute
    +parameters = " ".join([re.escape(a) for a in sys.argv[1:]])
    +# Test which tools exist
    +kdesudo = os.path.exists('/usr/bin/kdesudo')
    +gtksudo = os.path.exists('/usr/bin/gksudo')
    +# If we have at least one of them, check which one to use.
    +if kdesudo or gtksudo:
    +    if kdesudo and gtksudo:
    +        # Test if gnome runs
    +        process = subprocess.Popen("ps -ae | grep gnome-session", shell=True, stdout=subprocess.PIPE)
    +        process.wait()
    +        if len(process.communicate()[0])>0:
    +            useGnome = True
    +        else:
    +            useGnome = False
    +    elif kdesudo and (not gtksudo):
    +        useGnome = False
    +    elif (not kdesudo) and gtksudo:
    +        useGnome = True
    +    # really run it
    +    if useGnome:
    +        cmd = "gksudo "
    +    else:
    +        cmd = "kdesudo "
    +    # Run the actual program now
    +    os.system(cmd+parameters)
    +else:
    +    # we dont have gksudo or kdesudo, OMFG!
    +    cmd = "xterm -e \"echo 'Neither \\\"gksudo\\\" nor \\\"kdesudo\\\" have been found on your machine. Thus, \\\"sudo\\\" is being used. Please leave this window open until the program has finished. Your are asked for your password below.'; sudo "+parameters+"; sleep 1\""
    +    os.system(cmd)
     

    Disclaimer: el uso o no de SheBang/Declaracion de Encoding queda a criterio del usuario.

    diff --git a/recetario/xmladiccionario/index.html b/recetario/xmladiccionario/index.html index 024cc5505..6e4206211 100644 --- a/recetario/xmladiccionario/index.html +++ b/recetario/xmladiccionario/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    @@ -84,139 +84,139 @@

    Xml A Diccionario

    En este ejemplo se muestra cómo convertir un string a una estructura de diccionarios y listas anidadas usando expat. También se proveen dos clases que permiten manipular el resultado como si fueran objetos.

    Primero el código

    -
    import xml.parsers.expat
    -
    -class XmlParser(object):
    -    '''a class that parses a xml string an generates a nested
    -    dict/list structure
    -    '''
    -
    -    def __init__(self, text):
    -        '''constructor'''
    -        self.parser = xml.parsers.expat.ParserCreate()
    -        self.parser.buffer_text = True
    -
    -        self.result = None
    -        self.stack = []
    -        self.current = None
    -
    -        self.parser.StartElementHandler = self.start_element
    -        self.parser.EndElementHandler = self.end_element
    -        self.parser.CharacterDataHandler = self.char_data
    -        self.parser.Parse(text)
    -
    -    def start_element(self, name, attrs):
    -        '''Start xml element handler'''
    -        if self.current != None:
    -            self.stack.append(self.current)
    -
    -        self.current = {}
    -
    -        for (key, value) in attrs.iteritems():
    -            self.current[str(key)] = value
    -
    -        self.current['tag'] = name
    -        self.current['childs'] = []
    -
    -    def end_element(self, name):
    -        '''End xml element handler'''
    -        if len(self.stack):
    -            current = self.stack.pop()
    -            current['childs'].append(self.current)
    -            self.current = current
    -        else:
    -            self.result = self.current
    -
    -    def char_data(self, data):
    -        '''Char xml element handler.
    -        buffer_text is enabled, so this is the whole text element'''
    -        self.current['childs'].append(data)
    -
    -class DictObj(dict):
    -    '''a class that allows to access a dict as an object
    -    '''
    -
    -    def __init__(self, kwargs):
    -        '''constructor'''
    -        dict.__init__(self, kwargs)
    -
    -    def __getattribute__(self, name):
    -        if name in self:
    -            obj = self[name]
    -
    -            if type(obj) == dict:
    -                return DictObj(obj)
    -            elif type(obj) == list:
    -                return ListObj(obj)
    -
    -            return obj
    -        else:
    -            return None
    -
    -class ListObj(list):
    -    '''a class that allows to access dicts inside a list as objects
    -    '''
    -
    -    def __init__(self, args):
    -        '''constructor'''
    -        list.__init__(self, args)
    -
    -    def __getitem__(self, index):
    -        if index > len(self):
    -            raise IndexError('list index out of range')
    -
    -        obj = list.__getitem__(self, index)
    -
    -        if type(obj) == dict:
    -            return DictObj(obj)
    -        elif type(obj) == list:
    -            return ListObj(obj)
    -
    -        return obj
    -
    -    def __iter__(self):
    -        '''iterate over the list'''
    -
    -        count = 0
    -
    -        while count < len(self):
    -            yield self[count]
    -            count += 1
    -
    -def raw_string(dct_):
    -    '''return a string containing just the string parts removing all the
    -    xml stuff'''
    -
    -    def helper(dct):
    -        result = []
    -
    -        for child in dct.childs:
    -            if type(child) == str or type(child) == unicode:
    -                result.append(str(child))
    -            else:
    -                result = result + helper(child)
    -
    -        return result
    -
    -    return ''.join(helper(dct_))
    +
    import xml.parsers.expat
    +
    +class XmlParser(object):
    +    '''a class that parses a xml string an generates a nested
    +    dict/list structure
    +    '''
    +
    +    def __init__(self, text):
    +        '''constructor'''
    +        self.parser = xml.parsers.expat.ParserCreate()
    +        self.parser.buffer_text = True
    +
    +        self.result = None
    +        self.stack = []
    +        self.current = None
    +
    +        self.parser.StartElementHandler = self.start_element
    +        self.parser.EndElementHandler = self.end_element
    +        self.parser.CharacterDataHandler = self.char_data
    +        self.parser.Parse(text)
    +
    +    def start_element(self, name, attrs):
    +        '''Start xml element handler'''
    +        if self.current != None:
    +            self.stack.append(self.current)
    +
    +        self.current = {}
    +
    +        for (key, value) in attrs.iteritems():
    +            self.current[str(key)] = value
    +
    +        self.current['tag'] = name
    +        self.current['childs'] = []
    +
    +    def end_element(self, name):
    +        '''End xml element handler'''
    +        if len(self.stack):
    +            current = self.stack.pop()
    +            current['childs'].append(self.current)
    +            self.current = current
    +        else:
    +            self.result = self.current
    +
    +    def char_data(self, data):
    +        '''Char xml element handler.
    +        buffer_text is enabled, so this is the whole text element'''
    +        self.current['childs'].append(data)
    +
    +class DictObj(dict):
    +    '''a class that allows to access a dict as an object
    +    '''
    +
    +    def __init__(self, kwargs):
    +        '''constructor'''
    +        dict.__init__(self, kwargs)
    +
    +    def __getattribute__(self, name):
    +        if name in self:
    +            obj = self[name]
    +
    +            if type(obj) == dict:
    +                return DictObj(obj)
    +            elif type(obj) == list:
    +                return ListObj(obj)
    +
    +            return obj
    +        else:
    +            return None
    +
    +class ListObj(list):
    +    '''a class that allows to access dicts inside a list as objects
    +    '''
    +
    +    def __init__(self, args):
    +        '''constructor'''
    +        list.__init__(self, args)
    +
    +    def __getitem__(self, index):
    +        if index > len(self):
    +            raise IndexError('list index out of range')
    +
    +        obj = list.__getitem__(self, index)
    +
    +        if type(obj) == dict:
    +            return DictObj(obj)
    +        elif type(obj) == list:
    +            return ListObj(obj)
    +
    +        return obj
    +
    +    def __iter__(self):
    +        '''iterate over the list'''
    +
    +        count = 0
    +
    +        while count < len(self):
    +            yield self[count]
    +            count += 1
    +
    +def raw_string(dct_):
    +    '''return a string containing just the string parts removing all the
    +    xml stuff'''
    +
    +    def helper(dct):
    +        result = []
    +
    +        for child in dct.childs:
    +            if type(child) == str or type(child) == unicode:
    +                result.append(str(child))
    +            else:
    +                result = result + helper(child)
    +
    +        return result
    +
    +    return ''.join(helper(dct_))
     

    Simplemente creamos un objeto de tipo XmlParser pasándole el string y obtenemos el resultado parseado en la variable result. Si no queremos andar preguntado si las llaves existen antes de accederlas para evitar excepciones podemos usar la clase DictObj que nos permite acceder a las llaves como si fueran atributos, las variables que no existan como llaves contendran None. Acá va un ejemplo en la consola interactiva:

    -
    >>> import XmlParser
    ->>> p = XmlParser.XmlParser('<span><a href="google.com">go<s>o</s>gle</a> <i>test</i> <img src="foo.png" alt="foo"/> <u>!</u><s>!</s></span>')
    ->>> r = p.result
    ->>> d = XmlParser.DictObj(r)
    ->>> d
    -{'childs': [{'childs': [u'go', {'childs': [u'o'], 'tag': u's'}, u'gle'], 'href': u'google.com', 'tag': u'a'}, u' ', {'childs': [u'test'], 'tag': u'i'}, u' ', {'childs': [], 'src': u'foo.png', 'alt': u'foo', 'tag': u'img'}, u' ', {'childs': [u'!'], 'tag': u'u'}, {'childs': [u'!'], 'tag': u's'}], 'tag': u'span'}
    ->>> d.childs
    -[{'childs': [u'go', {'childs': [u'o'], 'tag': u's'}, u'gle'], 'href': u'google.com', 'tag': u'a'}, u' ', {'childs': [u'test'], 'tag': u'i'}, u' ', {'childs': [], 'src': u'foo.png', 'alt': u'foo', 'tag': u'img'}, u' ', {'childs': [u'!'], 'tag': u'u'}, {'childs': [u'!'], 'tag': u's'}]
    ->>> d.childs[0]
    -{'childs': [u'go', {'childs': [u'o'], 'tag': u's'}, u'gle'], 'href': u'google.com', 'tag': u'a'}
    ->>> d.childs[0].tag
    -u'a'
    ->>> d.childs[0].childs[0]
    -u'go'
    ->>> d.childs[0].childs[1].tag
    -u's'
    +
    >>> import XmlParser
    +>>> p = XmlParser.XmlParser('<span><a href="google.com">go<s>o</s>gle</a> <i>test</i> <img src="foo.png" alt="foo"/> <u>!</u><s>!</s></span>')
    +>>> r = p.result
    +>>> d = XmlParser.DictObj(r)
    +>>> d
    +{'childs': [{'childs': [u'go', {'childs': [u'o'], 'tag': u's'}, u'gle'], 'href': u'google.com', 'tag': u'a'}, u' ', {'childs': [u'test'], 'tag': u'i'}, u' ', {'childs': [], 'src': u'foo.png', 'alt': u'foo', 'tag': u'img'}, u' ', {'childs': [u'!'], 'tag': u'u'}, {'childs': [u'!'], 'tag': u's'}], 'tag': u'span'}
    +>>> d.childs
    +[{'childs': [u'go', {'childs': [u'o'], 'tag': u's'}, u'gle'], 'href': u'google.com', 'tag': u'a'}, u' ', {'childs': [u'test'], 'tag': u'i'}, u' ', {'childs': [], 'src': u'foo.png', 'alt': u'foo', 'tag': u'img'}, u' ', {'childs': [u'!'], 'tag': u'u'}, {'childs': [u'!'], 'tag': u's'}]
    +>>> d.childs[0]
    +{'childs': [u'go', {'childs': [u'o'], 'tag': u's'}, u'gle'], 'href': u'google.com', 'tag': u'a'}
    +>>> d.childs[0].tag
    +u'a'
    +>>> d.childs[0].childs[0]
    +u'go'
    +>>> d.childs[0].childs[1].tag
    +u's'
     
    diff --git a/recetariointerfaces_graficas/index.html b/recetariointerfaces_graficas/index.html index a67776b43..5044459d1 100644 --- a/recetariointerfaces_graficas/index.html +++ b/recetariointerfaces_graficas/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    diff --git a/recursos/index.html b/recursos/index.html index 8767714f1..b49578a07 100644 --- a/recursos/index.html +++ b/recursos/index.html @@ -28,7 +28,7 @@ Consejo ayudanos a pasar esta lista a la nueva sección específica "> - + Ir al contenido principal @@ -62,12 +62,12 @@ - +
    diff --git a/remeras/index.html b/remeras/index.html index 65a4b93b9..fb532fed5 100644 --- a/remeras/index.html +++ b/remeras/index.html @@ -26,7 +26,7 @@ Acá pueden ver el artwork original del cual salieron, creado alguna noche allá en otra"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/remerasv2/index.html b/remerasv2/index.html index 37546b6f3..41d9c36fa 100644 --- a/remerasv2/index.html +++ b/remerasv2/index.html @@ -27,7 +27,7 @@ Esta es toda la info de los sufragios, con las direcciones de mail saneadas: Por favor, anotá en RemerasV2/PreAnotado"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/remerasv3/index.html b/remerasv3/index.html index 91801a6d0..f264abf66 100644 --- a/remerasv3/index.html +++ b/remerasv3/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/rendimientopythonvsjavavsnet/index.html b/rendimientopythonvsjavavsnet/index.html index 2819bf404..3745e8270 100644 --- a/rendimientopythonvsjavavsnet/index.html +++ b/rendimientopythonvsjavavsnet/index.html @@ -35,7 +35,7 @@ Habría que ver b"> - + Ir al contenido principal @@ -69,12 +69,12 @@ - + diff --git a/renzocarbonara/index.html b/renzocarbonara/index.html index 5ba2c3321..395f26d34 100644 --- a/renzocarbonara/index.html +++ b/renzocarbonara/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/reuniones/index.html b/reuniones/index.html index b57180403..c00d780df 100644 --- a/reuniones/index.html +++ b/reuniones/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/reuniontemplate/index.html b/reuniontemplate/index.html index d080c76d9..da349ae23 100644 --- a/reuniontemplate/index.html +++ b/reuniontemplate/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/ricardokirkner/index.html b/ricardokirkner/index.html index 720dcba56..a3524bf60 100644 --- a/ricardokirkner/index.html +++ b/ricardokirkner/index.html @@ -26,7 +26,7 @@ Para mayor información pueden acceder a mis perfiles online Página personal: http://www.kirk"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/ricardoquesada/index.html b/ricardoquesada/index.html index 69ac23c16..330c64a4c 100644 --- a/ricardoquesada/index.html +++ b/ricardoquesada/index.html @@ -30,7 +30,7 @@ Me gusta Python: Desarrollos elegantes a alta velocidad Empecé con BASIC en la Commodore 64, luego aprendí assembler "> - + Ir al contenido principal @@ -64,12 +64,12 @@ - + diff --git a/robertoallende/index.html b/robertoallende/index.html index 60c1ba5cf..483d9b6d8 100644 --- a/robertoallende/index.html +++ b/robertoallende/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/robertoperdomo/index.html b/robertoperdomo/index.html index c939e1f4e..b6905ffb9 100644 --- a/robertoperdomo/index.html +++ b/robertoperdomo/index.html @@ -27,7 +27,7 @@ Desarrollo sistemas para la Universidad Central de Venezuela con web2py. S"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/robertorodriguez/index.html b/robertorodriguez/index.html index e67e0c3d8..d557613fd 100644 --- a/robertorodriguez/index.html +++ b/robertorodriguez/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/rss.xml b/rss.xml index f15a8b9c1..ba07fcc02 100644 --- a/rss.xml +++ b/rss.xml @@ -1,2 +1,2 @@ -Python Argentina Wikihttps://wiki.python.org.ar/Python Argentina WikiesContents © 2024 <a href="mailto:admin@python.org.ar">Python Argentina</a> Sun, 30 Jun 2024 14:48:00 GMTNikola (getnikola.com)http://blogs.law.harvard.edu/tech/rss \ No newline at end of file +Python Argentina Wikihttps://wiki.python.org.ar/Python Argentina WikiesContents © 2024 <a href="mailto:admin@python.org.ar">Python Argentina</a> Fri, 05 Jul 2024 22:39:58 GMTNikola (getnikola.com)http://blogs.law.harvard.edu/tech/rss \ No newline at end of file diff --git a/santafe/index.html b/santafe/index.html index 669a40819..40c3eb8b8 100644 --- a/santafe/index.html +++ b/santafe/index.html @@ -29,7 +29,7 @@ Presentación de los integrantes Presentacíon de cada integrante y actividad actual, a modo de conocernos"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/santiagobruno/index.html b/santiagobruno/index.html index 3e3868ee4..5adb96cab 100644 --- a/santiagobruno/index.html +++ b/santiagobruno/index.html @@ -26,7 +26,7 @@ Soy rafaelino y vivo en Córdoba. Soy Licenciado en Ciencias de la Computación egresado de Fa.M.A.F. (Universidad Nacional de Córdoba) Utilizo Pyt"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/santiagopereson/index.html b/santiagopereson/index.html index 3cc0108fc..5eb3e7230 100644 --- a/santiagopereson/index.html +++ b/santiagopereson/index.html @@ -29,7 +29,7 @@ Oveja Eléctrica: un compositor no humano (mucho python, algo de C y programas auxiliares: csound, ecasound"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/santiagosuarezo/index.html b/santiagosuarezo/index.html index ca6ec0b2c..861911b64 100644 --- a/santiagosuarezo/index.html +++ b/santiagosuarezo/index.html @@ -26,7 +26,7 @@ Estoy rindiendo las últimas materias para recibirme de Ingeniero en sistemas de Información en la Universidad Tecnológica Nacional, Regional Rosario. Arranqué en"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/saturdaynightninja/index.html b/saturdaynightninja/index.html index b26b3c867..2783c6634 100644 --- a/saturdaynightninja/index.html +++ b/saturdaynightninja/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/scipyar/index.html b/scipyar/index.html index c2a97a4b3..037b7474b 100644 --- a/scipyar/index.html +++ b/scipyar/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/sebasgiustra/index.html b/sebasgiustra/index.html index dd3f7b9ee..679b080d4 100644 --- a/sebasgiustra/index.html +++ b/sebasgiustra/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/sebastianbassi/index.html b/sebastianbassi/index.html index 1e5fd5239..ab037b578 100644 --- a/sebastianbassi/index.html +++ b/sebastianbassi/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/sebastianlezica/index.html b/sebastianlezica/index.html index b396033b5..7f443c9e5 100644 --- a/sebastianlezica/index.html +++ b/sebastianlezica/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/sebastianseba/index.html b/sebastianseba/index.html index c88279493..8962ece96 100644 --- a/sebastianseba/index.html +++ b/sebastianseba/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/segundoproyecto/index.html b/segundoproyecto/index.html index 7b2975afc..11a58c35a 100644 --- a/segundoproyecto/index.html +++ b/segundoproyecto/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/sendfile/index.html b/sendfile/index.html index ce5d76293..b3ecb8867 100644 --- a/sendfile/index.html +++ b/sendfile/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/sergiovernis/index.html b/sergiovernis/index.html index 553a6c8a2..6cffd7b46 100644 --- a/sergiovernis/index.html +++ b/sergiovernis/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/servidor/index.html b/servidor/index.html index 29302d6bd..d2cfe5b05 100644 --- a/servidor/index.html +++ b/servidor/index.html @@ -37,7 +37,7 @@ Funcionando sobre mod-wsgi, bajo el usuario www-pyar Sobre Python2.6 por los sitios de pycon (s"> - + Ir al contenido principal @@ -71,12 +71,12 @@ - + diff --git a/simonrodriguez/index.html b/simonrodriguez/index.html index 74f8689f3..52be8e253 100644 --- a/simonrodriguez/index.html +++ b/simonrodriguez/index.html @@ -26,7 +26,7 @@ Email: [[MailTo(you AT SPAMFREE example DOT com)]] ..."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/sitemap.xml b/sitemap.xml index fa8d680c0..efcc38427 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -7,3534 +7,3534 @@ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> https://wiki.python.org.ar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/2018/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Admin/dominios/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AlejandroJCura/classdeco/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AlejandroJCura/compactoexquisito/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AlejandroJCura/graficos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/Autoridades/candidatos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/Minutas/20160412/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/Minutas/20160428/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/Minutas/20160510/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/Minutas/20160526/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/Minutas/20160614/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/Minutas/20160630/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/Minutas/20160712/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/Minutas/20160921/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/autoridades/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/encuesta/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/minutas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/AsociacionCivil/mision/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Bandera/cambiadas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Bandera/descalificadas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Bandera/detallevotos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Bandera/fotos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Bandera/propuestas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Bandera/resultados/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Bandera/variaciones/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/CambiosRecientes/test/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/django/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/foobar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/introduccionalaprogramacion/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/introduccionaldesarrollowebi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/introduccionaldesarrollowebii/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/introduccionaplone/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/introduccionapython/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/introducciongui_i/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/introducciongui_ii/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/optimizandopython/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/pyqt/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/python3000/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/tallerjuegos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/twisted/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/CharlasAbiertas2010/wxpython/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Conferencias/pyconar2014/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Donaciones/lala/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/GSoC/2019/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/GSoC/2022/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/GSoC/2023/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/GSoC/2024/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/GSoC/ideas/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Gui/Gtk/vbox/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/HGTTP/contabilidad/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/HGTTP/disertantes/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/HGTTP/equipo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/HGTTP/informacion/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/HGTTP/logistica/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/HGTTP/logistica_pre/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/HGTTP/lugar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/HGTTP/marketing/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/HGTTP/sponsoring/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ListaDeCorreo/bar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ListaDeCorreo/migracion/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/LlamadoasedePyconar2012/pyconar2012bsas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ManuelQui%C3%B1ones/PruebaCal/2010-09-04/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ManuelQui%C3%B1ones/PruebaCal/2010-10-15/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ManuelQui%C3%B1ones/PruebaCal/2010-10-16/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ManuelQui%C3%B1ones/PruebaCal/pycon2010/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ManuelQui%C3%B1ones/pruebacal/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/MarianoGuerra/holamundo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Material/agua/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/MatiasGieco/prueba01/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/2004/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/2005/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/2006/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/2007/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/2008/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/2009/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/2010/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/2011/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/aritmeticadecimal/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/fotobymail/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/gvrybandera/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/inmersion54/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/listadodepigs/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/python24/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Noticias/pythonpalm/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Planeta/config/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/CDPedia/Prensa/release07/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/CDPedia/Prensa/release08/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/CDPedia/Prensa/release082/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/CDPedia/changelogs/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/CDPedia/historia/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/CDPedia/modoservidor/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/CDPedia/prensa/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/CDPedia/versionesanteriores/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/GauchitoGil/eventmatching/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/PET1/desafio/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/PET2/articulos/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/PET2/comosehizo/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/PET2/decoradores/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/PET2/depuraciondefragmentacion/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/PET2/desafio/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/PET2/infopython/ - 2024-06-30T14:47:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/PET2/introdjango/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/PET2/pyafipws/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/base/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/pet2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/RevistaPythonComunidad/release1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/alocadoalocador/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/caucho/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/cdpedia/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/gauchitogil/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/geine/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/getesfi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/pythonpalm/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/revistapythoncomunidad/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/Proyectos/stim/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/tweetyfinger/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/unmanualencadauniversidad/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Proyectos/usodepythonenlauniversidad/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2009/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2009/TemasPropuestos/sprintdjango/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2009/comollegar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2009/fotos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2009/naushikang/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2009/programa/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2009/quienesvan/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2009/requerimientosdietarios/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2009/temaspropuestos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2009/transporte/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2010/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2010/attic/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2010/cronograma/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2010/delinterior/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2010/interesados/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2010/pendientes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2010/quellevar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2010/temaspropuestos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2010/torneopingpong/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2011/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2011/desdecordobacapital/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2011/interesados/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2011/proyectoslaburados/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2011/quellevar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2011/temasdesarrollados/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2011/temaspropuestos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2012/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2012/TemasPropuestos/editordeebooks/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2012/cronograma/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2012/interesados/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2012/kinect/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2012/proyectos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2012/quellevar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2012/temaspropuestos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2012/workshop/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2013/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2013/PosiblesSedes/votos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2013/becas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2013/habitaciones/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2013/posiblessedes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2013/temaspropuestos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2014/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2014/PosiblesSedes/votos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2014/becas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2014/posiblessedes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2014/rooming/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2014/temaspropuestos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2015/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2015/PosiblesSedes/votos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2015/actividades/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2015/posiblessedes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2016/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2016/Actividades/test/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2016/actividades/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2016/posiblessedes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2017/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2017/actividades/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2017/ayudaeconomica/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2017/posiblessedes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2018/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2018/actividades/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2018rst/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2019/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2019/actividades/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2019/posiblessedes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2020/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2021/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2022/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2023/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2024/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/2024/showntell2024/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/PyCamp/2018/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/coc/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/howto/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/organizandounpycamp/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyCamp/quesehace/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2009/alojamientocompartido/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2009/transportecompartido/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2012/alojamientocompartido/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/PyConArgentina/2012/distribucionafiches/ - 2024-06-30T14:47:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/PyConArgentina/2012/encargadosaula/ - 2024-06-30T14:47:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/PyConArgentina/2012/llamadopropuestas/ - 2024-06-30T14:47:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/PyConArgentina/2012/llamadorevisores/ - 2024-06-30T14:47:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/PyConArgentina/2012/llamadosponsors/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2012/llamadovoluntarios/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2012/tareaspendientes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2012/temaspendientes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2012/transportecompartido/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2012/workshop/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2013/ayuda/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2013/couchsurfing/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2013/llamadosedes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyConArgentina/2013/transportsurfing/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/PyDay2/callforcharlas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/alecu1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/cesarportela1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/cesarroldan1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/cesarroldan2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/cesarroldan3/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/facundobatista1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/facundobatista2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/facundobatista3/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/facundobatista4/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/facundobatista5/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/hernanbalocco1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/humitos1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/juanjo1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/laubenech1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/laubenech2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/laubenech3/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/laubenech4/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/laubenech5/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/laubenech6/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/nubis1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/nubis2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/pabloziliani1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/pabloziliani2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/preanotados/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/ramiromorales1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV2/solounejemplo0/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV3/leonardovidarte1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV3/leonardovidarte2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV3/leonardovidarte3/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV3/leonardovidarte4/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV3/luciotorre1/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV3/manuelarguelles1/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV3/manuelarguelles2/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV3/manuelarguelles3/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RemerasV3/pedidos/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RicardoKirkner/labanderadepyar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/RicardoKirkner/miembrosdepyar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/SebastianBassi/codigo1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/SebastianBassi/codigo2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ServidorPyAr/scsi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/TareasPendientes/tareasrealizadas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ToDo/tareasrealizadas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/Videohttp/pyaruslaorgar/orm001ogv/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/aafigure/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/aafigure/test/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/actividades/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/admin/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/admingroup/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/adoptaunnewbie/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/adrianpardini/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/afichepyconar2011/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/alberto-pastor/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/albertopaparelli/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/alecutest2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/alejandrodavidweil/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/alejandrojcura/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/alejandrosantos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/alejopagadizabal/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/alfonsopalomares/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/alojamientowebpython/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/angelfreire/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/angelvelasquez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/anthonylenton/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/aprendiendopython/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/archive.html - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ariel-alvarez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ariel-barrios/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/arturoeanton/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/asociacioncivil/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ayudadecontenidospy/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/badcontent/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/bandera/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/becaspyconar2011/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/blog/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/brygevel/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/buscandogente/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/buzospyar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/cafeconf2006/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/callforcharlas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/callforcharlasinvitaciontemplate/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/callforcharlastemplate/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/categories/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/categorycategory/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/caucho/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/cdpedia-on-android/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/cfcpyconar2011/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/charlas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/charlasabiertas2010/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/cherrypy/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/chistes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/circoerrante/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/clasesdepython/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/colaborandoenelwiki/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/colectadehardware/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/common_links/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/compilarpython/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/condornet/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/contribuyendoalwiki/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/cristianskalican/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/cronogramapyconar2011/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/danielmendoza/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/danielmoisset/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/davidlitvak/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/dbapi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/deretiroacordoba/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/desarrollador-jr-o-ssr-django-y-javascript/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/diegoahumada/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/diegosarmentero/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/dieresys/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/distutils/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/diversidad/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/edupython/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/edupythoncd/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ejercicios/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/elisabeth-hartwig/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eloycolell/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/emilianodallaverdemarcozzi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/emilioramirez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/empresasyprofesionales/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/enlosmedios/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/etiquetapyar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eugeniabahit/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/2016/reunion66/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/2jornadapythonstafe/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/8JRSL/carteles/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/8jrsl/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/Eventos/Conferencias/pyconar2013/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/ProcesoSeleccion/propuestadepycon2013encordobacapital/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/ProcesoSeleccion/propuestadepycon2013enrosario/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/PyConAr2016/propuestasedebahia/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/PyConAr2016/viaje/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/PyConAr2017/propuestasedecordoba/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/PyConAr2018/propuestasedecaba/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/PyConAr2020/propuestaejemplo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/cafeconf2006/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/procesoseleccion/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pycon2006/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pyconar2013/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pyconar2014/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pyconar2016/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pyconar2017/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pyconar2018/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pyconar2020/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pyconargentina2009/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pyconargentina2010/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pydaybuenosaires2010/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pydayrafaela2010/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Conferencias/pydayrafaela2012/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/PyCamp/2012/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/PyDay/2011/Cordoba/comunidadanarquiasubversion/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/PyDay/2011/Cordoba/pythonpilas/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/PyDay/2011/Cordoba/pythonsugaricaro/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/PyDay/2011/Cordoba/pythontests/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/PyDay/2011/cordoba/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2004/reunion01/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2004/reunion02/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2004/reunion03/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2004/reunion04/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2005/reunion05/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2005/reunion06/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2005/reunion07/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2005/reunion08/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2005/reunion09/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2005/reunion10/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2005/reunion11/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2005/reunion12/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2006/reunion13/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2006/reunion14/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2006/reunion15/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2006/reunion16/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2006/reunion17/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2006/reunion18/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2006/reunion19/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2006/reunion20/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2006/reunion21/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2007/reunion22/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2007/reunion23/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2007/reunion24/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2008/reunion25/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2008/reunion26/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2008/reunion27/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2008/reunion28/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2008/reunion29/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2008/reunion30/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2008/reunion31/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2008/reunion32/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2008/reunion33/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2008/reunion34/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2009/reunion35/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2009/reunion36/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2009/reunion37/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2009/reunion38/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2009/reunion39/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2010/reunion40/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2010/reunion41/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2010/reunion42/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2010/reunion43/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2010/reunion44/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2010/reunion45/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2010/reunion46/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2011/reunion47/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2011/reunion48/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2011/reunion49/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2011/reunion50/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2012/reunion51/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2012/reunion52/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2012/reunion53/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2012/reunion54/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2012/reunion55/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2012/reunion56/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2012/reunion57/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2012/reunion58/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2013/reunion59/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2013/reunion60/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2013/reunion61/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2014/reunion62/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2014/reunion63/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2014/reunion64/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2015/reunion65/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2016/reunion66/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2017/reunion67/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2017/reunion68/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/eventos/Reuniones/2017/reunion69/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2018/reunion70/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2019/reunion71/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/2019/reunion72/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/proximareunion/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Reuniones/releaseprocedure/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Sprints/olpcserver/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/Sprints/wikipediaoffline1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/conferencias/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/djangolaunchparty/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/pythonbugday/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/pythonday3/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/reuniones/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/eventos/sprints/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/extraermails/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ezequielmarquez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/facundobatista/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/filly/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/fixme/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/folletoscarteles/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/foo/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/foro_y_redes/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/fullsearchcachedcategorywxpython/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/fullsearchcategorycategoryvideo/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/gabrielbrunacci/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/gabrielgenellina/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/gastemosla/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/gatox/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/gauchitogil/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/gnomeart/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/gonzalodelgado/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/gonzalolarralde/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/gonzalopedone/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/grupo-de-entusiastas-de-python/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/gsoc/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/guardarhistorialenconsolainteractiva/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/guillermofreschi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/guillermogonzalez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/h/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/hectorsanchez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/helponmoinwikisynutax/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/hernanolivera/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/hgttp/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/hipbar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/horaciobertorello/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/horacioduran/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/howtoconferencia/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/hugoruscitti/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ideal/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ideas-para-programar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ides/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/infraestuctura/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/interesadosentrabajo/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/interfacesgraficas/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/invitacioncuentawave/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/irc/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/javiercastrillo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/joaquinsorianello/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/joaquintita/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/johnlenton/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/joseluisdallapiccola/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/juanfisanotti/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/juanjociarlante/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/juanjoconti/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/juegos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/juegos/typuspocus/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/juegos/worldst/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/kaufmannmanuel/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/kola/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/labanderadepyar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/leandrocolombovina/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/leitomonk/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/libreriasparajuegos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/lista-de-charlas-realizadas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/listab/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/listadecorreo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/llamadoasedepyconar2012/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/lucianorossi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/luciotorre/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/luis-nagel/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/mailtopyar-at-python-dot-org-dot-ar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/manuelquinones/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/maram/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/marceloalaniz/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/marcelofernandez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/marcosdione/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/marcosvanetta/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/marianodraghi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/marianogarcia/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/marianoguerra/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/marianomara/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/marianoreingart/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/marianoverdu/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/martinalderete/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/martinchikilian/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/martincontemacdonell/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/martingaitan/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/martinvolpe/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/material/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/materialpyconar2011/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/matiasbellone/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/matiasgieco/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/mauricio-josc3a920tobares/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/mauricioferrari/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/maximilianochurichi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/mensajesexcepcionales/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/merchandisingpyconar2011/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/2immarketing/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/acondori/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/agustin92/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/alejandra/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/alejandro_0101/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/amjalca/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/andres14/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/andresdevops/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/armando/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/becerra1982/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/benjapy/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/bgeninatti/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/btenaglia/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/buongarzoni/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/carasucia/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/carloscarlossouthpalscom/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/centertek/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/cesarroldan/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/cmenta/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/correanicolas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/crisovando/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/danis/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/danymana/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/debianitram/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/debrivero/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/dgonzalez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/diegoduncan21/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/dnc91/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/edwinr2000/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/ekimal/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/eliobastias/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/empoisoner/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/ernestto/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/facundobatista/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/falcho/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/fausto10/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/ferjavrec/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/fernandolamasw/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/fideo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/franco_jerke/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/frobriel/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/fullpaint/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/gavalen/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/gbaume/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/gilgamezh/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/ginomarcellino/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/guido/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/gustavofurlan/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/hatsem78/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/herchila/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/humitos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/idoneus/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/ignacionicolasalvarez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/inafontan/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/inokis/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/intligente/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/jdromero1/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/jigcau89/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/jorgermc123/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/joseernestomoralesventura/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/jotajota-2012/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/jquintas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/juanandres438/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/juanpablo064/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/keyleron/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/knonical/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/lacpac23/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/lucaspyar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/luciano1994/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/martingaitan/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/matiasgabrieln/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/matibarriento/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/mauriciobaeza/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/maurosl/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/mbaragiola/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/mirlo/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/mmartinovic/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/noeliabruscoli/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/nrivollier/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/numaelis/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/oconner/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/pab/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/pamparider/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/patricio81/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/ramon27/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/rbellanti/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/salbarracin/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/miembros/sam/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/scrdsindia/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/sebasgiustra/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/sebbasfernandez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/seelaff/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/selfprint/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/skrullchull/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/soneban/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/ssebastianj/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/ssergio/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/sserrano44/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/sysface/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/tapicer/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/teury/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/tin/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/tomyfer11/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/uxun/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/victor/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/vonpixarg/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/walexnet/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/walteralini/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/werben/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/wolchesky/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembros/zontxo/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miembrosdepyar/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/miniejemplos/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/minifaq/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/mudanzaservidoresdominio/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/nickar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/nicocesar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/nicoechaniz/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/nicolasdemarchi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/noticias/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/nubis/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/nuevologo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/nuevositio/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/obteniendorespuestas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/omar-vega/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/orms/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/osiris/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pabloalejandrocostesich/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pablopetenello/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pabloseminario/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pabloziliani/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/patriciomolina/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pep/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/planeta/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/plpython/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/preferenciasdelusuario/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/preguntasfrecuentes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/preguntassinrespuesta/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/primerproyecto/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/proximareunion/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/proyecto/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/proyectos/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/prueba/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pruebaloca/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pruebamail/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pruebavideo/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/py2exe/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pyar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pycamp/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pycamp2009resultados/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pycamporm/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pycon/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pyconapp/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/pyconar2015/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/pyconarvotacioncharlas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/pyday/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/pyday2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/pydayjunin2015/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/python-ya/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/python3mil/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/pythoneneldiaadia/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/pythonzen/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/pyweek/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/quienessomos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/ramiroalgozino/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/ramiromorales/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/readwritegroup/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/alarmaprecaria/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/aletras/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/autocomplecionenconsolainteractiva/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/bloquearclickdelmouse/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/botongraficotk/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/bottle/galeria/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/bottle/holamundo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/calculardigitoverificadormodulodiez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/checkdistroversion/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/chequearinterfacesinternetlinux/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/chequeo_de_paquetes_apt_linux/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/comobajartodoslosbuffersaldisco/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/comolevantarunservidorhttpmultithread/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/comolevantarunservidorhttpsimple/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/comunicarthreadsconqueue/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/creandounnuevoproyectopython/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/crearejecutablewindows/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/crearejecutablewindowsdesdelinux/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/crypto/blowfishconblowfishpy/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/dbfpy/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/decodehtmlentities/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/displaylcd7segmentos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/django/obtenerclaseoriginalcuandohayherencia/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/django/testformularioconfileupload/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/emailconadjunto/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/entendiendounicode/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/estilosrst2pdf/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/extraermails/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/facturapyfpdf/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/fun/minispaceinvaders/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/fun/nadosincronizado/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/fun/nadosincronizadodisco/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gmailmail/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gtkontk/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/autocomplete/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/browserconwebinspector/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/button/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/buttonbox/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/confirmclose/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/dialog/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/emuladorterminal/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/entry/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/entrysolonumeros/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/erorhandler/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/errorhandler/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/funcionrunner/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/gladeholamundooo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/grid/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/hbox/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/holamundo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/holamundooo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/labelconcolor/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/listview/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/menu/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/multithread/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/multithread2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/gui/gtk/printnongtk/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/richtext/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/runner/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/statusicon/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/stockitems/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/vbox/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/webkiteditor/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/gui/gtk/xmlrpcserver/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/histograma/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/interceptarprints/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/ippublica/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/iterarsobrepares/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/keyboardledsdemo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/listarprocesos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/localsdeunafuncionquelanzounaexcepcion/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/mapeandomemoria/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/matrixpythontoy/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/multiprocessingythreading/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/normalizarcaracteresunicode/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/notificardispositivosusb/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/obtenerbytestransferidos/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/obtenersensaciontermica/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/obtenerubicaciongeografica/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/pasarrecaptcha/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/progressbarurllib2/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/psycospeedup/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/pythoncard/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/pythonversioncheck/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/pyuno/holamundo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/pyuno/miprimermacro/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/qt/qtextraertextorecurso/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/qt/qtimprimirpagina/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/qt/qtmultithread/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/relojdigital/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/reverse/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/revisarconexion/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/rootcheck/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/sabersinlibreriaestainstalada/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/servidorcom/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/simplesoapclient/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/simplexmlelement/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/tkbuttonicon/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/tkonlineofflineicon/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/tkscrollwhell/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/tkversionprint/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/tkwindowicon/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/tkwizards/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/ttkholamundo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/validarcuit/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/ventanapasswordvibra/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/recetario/winbatt/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/xdg-sudo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetario/xmladiccionario/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recetariointerfaces_graficas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/recursos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/remeras/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/remerasv2/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/remerasv3/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/rendimientopythonvsjavavsnet/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/renzocarbonara/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/reuniones/ - 2024-06-30T14:47:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/reuniontemplate/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ricardokirkner/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/ricardoquesada/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/robertoallende/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/robertoperdomo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/robertorodriguez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/santafe/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/santiagobruno/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/santiagopereson/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/santiagosuarezo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/saturdaynightninja/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/scipyar/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/sebasgiustra/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/sebastianbassi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/sebastianlezica/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/sebastianseba/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/segundoproyecto/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/sendfile/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/sergiovernis/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/servidor/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/simonrodriguez/ - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z https://wiki.python.org.ar/snippets/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/stickers/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/sugerencias/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/tablaides/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/tallerolpc/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/tareaspendientes/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/temp/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/terminalesinteractivas/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/test/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/texteditordeadmatch/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/themostbiggestgamestintheworldst/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/todo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/toquetonesgroup/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/trabajo/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/trabajos/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/tracebackinternationalizationproposal/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/tutorial/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/unicode/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/unmanualencadauniversidad/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/usodepythonenlauniversidad/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/usuariosbuscandohosting/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/venenito/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/viaje/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/videotemplate/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/visualbasic/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/vpss/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/walikioff/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/walteralini/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/web2py/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/webkit/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/whyfloss/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/willsantana/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/wsgi/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/wwwhexactacom/ - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z \ No newline at end of file diff --git a/sitemapindex.xml b/sitemapindex.xml index 6031422a7..3042d24a3 100644 --- a/sitemapindex.xml +++ b/sitemapindex.xml @@ -7,10 +7,10 @@ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> https://wiki.python.org.ar/rss.xml - 2024-06-30T14:48:00Z + 2024-07-05T22:39:00Z https://wiki.python.org.ar/sitemap.xml - 2024-06-30T14:48:00Z + 2024-07-05T22:40:00Z \ No newline at end of file diff --git a/snippets/index.html b/snippets/index.html index f29c9f1e3..911bdbda1 100644 --- a/snippets/index.html +++ b/snippets/index.html @@ -26,7 +26,7 @@ entrar a la pagina personal (http:/"> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/stickers/index.html b/stickers/index.html index 63dd2f3d8..e20d72f91 100644 --- a/stickers/index.html +++ b/stickers/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/sugerencias/index.html b/sugerencias/index.html index d8972049b..18cfc4b04 100644 --- a/sugerencias/index.html +++ b/sugerencias/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/tablaides/index.html b/tablaides/index.html index 617b608c8..6f431731a 100644 --- a/tablaides/index.html +++ b/tablaides/index.html @@ -26,7 +26,7 @@ Tabla comparativa de las features de algunos IDEs disponibles para programar en python."> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/tallerolpc/index.html b/tallerolpc/index.html index 6ca2d6e87..9d3b6b41b 100644 --- a/tallerolpc/index.html +++ b/tallerolpc/index.html @@ -28,7 +28,7 @@ Módulo OLPCGames: http://dev.laptop.org/~mcfletch/OLPCGames/OLPCGames-1.6.zip Imag"> - + Ir al contenido principal @@ -62,12 +62,12 @@ - + @@ -87,7 +87,7 @@

    Taller Olpc

    Para bajar la charla y todos los ejemplos:

    -
    svn checkout http://charla-pygame.googlecode.com/svn/trunk/ charla-pygame
    +
    svn checkout http://charla-pygame.googlecode.com/svn/trunk/ charla-pygame
     

    Módulo OLPCGames: http://dev.laptop.org/~mcfletch/OLPCGames/OLPCGames-1.6.zip

    Imagen de Qemu:

    @@ -101,32 +101,32 @@

    Taller Olpc

    • Instalar qemu y kqemu. En ubuntu:

    -
    sudo apt-get install qemu kqemu-source kqemu-common
    -sudo module-assistant prepare kqemu
    -sudo module-assistant auto-install kqemu
    -sudo modprobe kqemu
    +
    sudo apt-get install qemu kqemu-source kqemu-common
    +sudo module-assistant prepare kqemu
    +sudo module-assistant auto-install kqemu
    +sudo modprobe kqemu
     
    • bajarse y descomprimir la imagen de olpc:

    -
    mkdir ~/olpc
    -cd ~/olpc
    -wget http://xs-dev.laptop.org/~cscott/xo-1/streams/ship.2/build659/devel_ext3/olpc-redhat-stream-ship.2-build-659-20080229_1949-devel_ext3.img.bz2
    -bunzip xo-1-olpc-stream-update.1-devel_ext3.img.bz2
    -chmod -w xo-1-olpc-stream-update.1-devel_ext3.img
    +
    mkdir ~/olpc
    +cd ~/olpc
    +wget http://xs-dev.laptop.org/~cscott/xo-1/streams/ship.2/build659/devel_ext3/olpc-redhat-stream-ship.2-build-659-20080229_1949-devel_ext3.img.bz2
    +bunzip xo-1-olpc-stream-update.1-devel_ext3.img.bz2
    +chmod -w xo-1-olpc-stream-update.1-devel_ext3.img
     
    • crear la imagen "Copy on Write" de qemu:

    -
    mkdir /tmp/olpc
    -cd /tmp/olpc
    -qemu-img create -b ~/olpc/xo-1-olpc-stream-update.1-devel_ext3.img -f qcow olpc.img
    +
    mkdir /tmp/olpc
    +cd /tmp/olpc
    +qemu-img create -b ~/olpc/xo-1-olpc-stream-update.1-devel_ext3.img -f qcow olpc.img
     
    • bootear qemu:

    -
    cd /tmp/olpc
    -qemu -m 256 -kernel-kqemu -soundhw es1370 -net user -net nic,model=rtl8139 -hda olpc.img
    +
    cd /tmp/olpc
    +qemu -m 256 -kernel-kqemu -soundhw es1370 -net user -net nic,model=rtl8139 -hda olpc.img
     
    diff --git a/tareaspendientes/index.html b/tareaspendientes/index.html index b2cfbceb2..f589e5b5b 100644 --- a/tareaspendientes/index.html +++ b/tareaspendientes/index.html @@ -29,7 +29,7 @@ Agregar al archivo data/intermap.txt del moinmoin de PyAr las siguiente linea PyArTrac h"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - +
    diff --git a/temp/index.html b/temp/index.html index 4926deccf..22e526276 100644 --- a/temp/index.html +++ b/temp/index.html @@ -32,7 +32,7 @@ Cristina Pedrani Cynthia M"> - + Ir al contenido principal @@ -66,12 +66,12 @@ - +
    diff --git a/terminalesinteractivas/index.html b/terminalesinteractivas/index.html index 648b4ad65..a144df8a9 100644 --- a/terminalesinteractivas/index.html +++ b/terminalesinteractivas/index.html @@ -27,7 +27,7 @@ Python Esta es la consola por defecto que se instala con Python, para eje"> - + Ir al contenido principal @@ -61,12 +61,12 @@ - +
    diff --git a/test/index.html b/test/index.html index c9e7eb2a4..c13a688ca 100644 --- a/test/index.html +++ b/test/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - +
    diff --git a/texteditordeadmatch/index.html b/texteditordeadmatch/index.html index fd87f6ca8..4b1c817ab 100644 --- a/texteditordeadmatch/index.html +++ b/texteditordeadmatch/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +
    diff --git a/themostbiggestgamestintheworldst/index.html b/themostbiggestgamestintheworldst/index.html index 07ba32126..0cb31fde8 100644 --- a/themostbiggestgamestintheworldst/index.html +++ b/themostbiggestgamestintheworldst/index.html @@ -32,7 +32,7 @@ "> - + Ir al contenido principal @@ -66,12 +66,12 @@ - + diff --git a/todo/index.html b/todo/index.html index e3df6b8de..b482e5ddb 100644 --- a/todo/index.html +++ b/todo/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/toquetonesgroup/index.html b/toquetonesgroup/index.html index 8d8918fdf..c1e6aab16 100644 --- a/toquetonesgroup/index.html +++ b/toquetonesgroup/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/trabajo/index.html b/trabajo/index.html index 9429897f9..898ce2f50 100644 --- a/trabajo/index.html +++ b/trabajo/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/trabajos/index.html b/trabajos/index.html index be04948bf..9c894060e 100644 --- a/trabajos/index.html +++ b/trabajos/index.html @@ -26,7 +26,7 @@ pero ahora tenemos una sección trabajos donde es mucho más fácil publicar ofertas y postulaciones. "> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/tracebackinternationalizationproposal/index.html b/tracebackinternationalizationproposal/index.html index 3f9c89f06..e3bea708c 100644 --- a/tracebackinternationalizationproposal/index.html +++ b/tracebackinternationalizationproposal/index.html @@ -31,7 +31,7 @@ Type: Standards Track Content-Type: text/plain"> - + Ir al contenido principal @@ -65,12 +65,12 @@ - + diff --git a/tutorial/index.html b/tutorial/index.html index b004c3833..1c499edba 100644 --- a/tutorial/index.html +++ b/tutorial/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -87,7 +87,7 @@

    Tutorial

    La última versión de Py2 traducido fue 2.7.3, mientras que la última versión de Python liberada es la 3.5.0 Final y está cubierta en nuestra traducción 😉

    Las versiones en HTML y los respectivos PDFs se pueden acceder aquí.

    El proyecto con todas las fuentes e instrucciones para la generación de los diferentes formatos lo tenemos en GitHub, para obtener una copia hacer:

    -
    git clone git@github.com:PyAr/tutorial.git
    +
    git clone git@github.com:PyAr/tutorial.git
     
    diff --git a/unicode/index.html b/unicode/index.html index bf358dc81..e52bcc6ae 100644 --- a/unicode/index.html +++ b/unicode/index.html @@ -29,7 +29,7 @@ Pragmatic Unicode The Absolute Minimum Every Software Developer Absolutely, Positively Must"> - + Ir al contenido principal @@ -63,12 +63,12 @@ - + diff --git a/unmanualencadauniversidad/index.html b/unmanualencadauniversidad/index.html index cdc944359..4b00b232e 100644 --- a/unmanualencadauniversidad/index.html +++ b/unmanualencadauniversidad/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/usodepythonenlauniversidad/index.html b/usodepythonenlauniversidad/index.html index d9b32fff2..2cc09b847 100644 --- a/usodepythonenlauniversidad/index.html +++ b/usodepythonenlauniversidad/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/usuariosbuscandohosting/index.html b/usuariosbuscandohosting/index.html index 5d58be54c..487696a0c 100644 --- a/usuariosbuscandohosting/index.html +++ b/usuariosbuscandohosting/index.html @@ -26,7 +26,7 @@ "> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/venenito/index.html b/venenito/index.html index f89863cd0..4f6430565 100644 --- a/venenito/index.html +++ b/venenito/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/viaje/index.html b/viaje/index.html index 7337d9c76..893a7eb8a 100644 --- a/viaje/index.html +++ b/viaje/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/videotemplate/index.html b/videotemplate/index.html index dcbe9ecaf..1e7a179b7 100644 --- a/videotemplate/index.html +++ b/videotemplate/index.html @@ -36,7 +36,7 @@ Código:"> - + Ir al contenido principal @@ -70,12 +70,12 @@ - + diff --git a/visualbasic/index.html b/visualbasic/index.html index 4826bac3d..fff04adb7 100644 --- a/visualbasic/index.html +++ b/visualbasic/index.html @@ -27,7 +27,7 @@ D'> - + Ir al contenido principal @@ -61,12 +61,12 @@ - + diff --git a/vpss/index.html b/vpss/index.html index 11bce2b03..81e2cc2b4 100644 --- a/vpss/index.html +++ b/vpss/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/walikioff/index.html b/walikioff/index.html index e76317320..376edad70 100644 --- a/walikioff/index.html +++ b/walikioff/index.html @@ -26,7 +26,7 @@ Hola! Si llegaste a esta url significa que estás queriendo editar nuestro contenido. ¡Gracias! Lamentablemente estuvimos recibiendo mucho SPAM y nuestra wiki "> - + Ir al contenido principal @@ -60,12 +60,12 @@ - + diff --git a/walteralini/index.html b/walteralini/index.html index 899a53d7f..321e07163 100644 --- a/walteralini/index.html +++ b/walteralini/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/web2py/index.html b/web2py/index.html index d81163051..801629ccc 100644 --- a/web2py/index.html +++ b/web2py/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -108,11 +108,11 @@

    Web2py

  • Iniciar web2py.py

  • Ejemplo:

    -
    sudo apt-get install python psycopg2
    -wget http://www.web2py.com/examples/static/web2py_src.zip
    -unzip web2py_src.zip
    -cd web2py
    -python web2py.py
    +
    sudo apt-get install python psycopg2
    +wget http://www.web2py.com/examples/static/web2py_src.zip
    +unzip web2py_src.zip
    +cd web2py
    +python web2py.py
     

    Recorrida

    A continuación mostraremos una breve recorrida sobre las características principales de web2py.

    diff --git a/webkit/index.html b/webkit/index.html index cf0bbc071..63c866452 100644 --- a/webkit/index.html +++ b/webkit/index.html @@ -24,7 +24,7 @@ - + Ir al contenido principal @@ -58,12 +58,12 @@ - + diff --git a/whyfloss/index.html b/whyfloss/index.html index b3cc3b625..f541a708a 100644 --- a/whyfloss/index.html +++ b/whyfloss/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/willsantana/index.html b/willsantana/index.html index d8f3279f9..59cc5d293 100644 --- a/willsantana/index.html +++ b/willsantana/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + diff --git a/wsgi/index.html b/wsgi/index.html index 4e0c13d35..df9edc65a 100644 --- a/wsgi/index.html +++ b/wsgi/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - + @@ -90,15 +90,15 @@

    Web Server Gateway Interface

  • Del lado de la aplicación, se especifica un punto de entrada (objeto, método, función), con dos parámetros: las variables de entorno (environ y la función para iniciar la respuesta start_response(status,response_headers) que envía el estado y los encabezados), y debe devolver un iterable con los datos para enviar al cliente.

  • Del lado del servidor, se invoca la aplicación por cada pedido que recibe del cliente HTTP, con las variables de entorno establecidas (estilo CGI)

  • Ejemplo

    -
    # Aqui va mi 'Hola PyAr!, pero con WSGI, una maravilla de Python.
    -
    -from wsgiref.simple_server import make_server
    -
    -def hello(environ, start_response):
    -    start_response('200 OK',[('Content-type','text/plain')])
    -    return ['Hola PyAr!']
    -
    -httpd = make_server('',8000, hello).serve_forever()
    +
    # Aqui va mi 'Hola PyAr!, pero con WSGI, una maravilla de Python.
    +
    +from wsgiref.simple_server import make_server
    +
    +def hello(environ, start_response):
    +    start_response('200 OK',[('Content-type','text/plain')])
    +    return ['Hola PyAr!']
    +
    +httpd = make_server('',8000, hello).serve_forever()
     

    (copiado de un mail "hello-word" de la lista)

    Variables de entorno (diccionario {{{environ}}})

    @@ -123,44 +123,44 @@

    Web Server Gateway Interface

    Igualmente, estos Handlers no son compatibles con WSGI, por eso no recomendaría usar ninguno de ellos directamente, sino a través del wrapper WSGI (con ModPythonGateway) que es un handler "propio" que traduce las peticiones al estandar WSGI. Es algo mucho mas estandar, valga la redundancia, y el día de mañana se puede usar cualquier servidor compatible con python, no solo apache.

    Además, puede utilizarse directamente mod_wsgi (ver siguiente sección).

    Ejemplos de configuración (tanto en /etc/apache2/... en un archivo .htaccess en el mismo directorio):

    -
    # handler Publisher:
    -#  se ejecutará cualquier archivo .py del directorio, llamando a la función de la url:
    -#  http://www.mysite.com/hello.py/say  ejecutara el script hello.py, funcion say
    -<Directory /var/www/html/python/>
    -    SetHandler mod_python
    -    PythonHandler mod_python.publisher
    -    PythonDebug On
    -</Directory>
    -
    -# Handler PSP:
    -#  se ejecutará cualquier archivo .psp (código python embebido en texto html)
    -<Directory /var/www/html/psp/>
    -   AddHandler mod_python .psp
    -   PythonHandler mod_python.psp
    -</Directory>
    -
    -# Handler CGI:
    -#  se ejecutará los scripts .py (scripts normales de python) simil linea de comandos
    -<Directory /var/www/cgi-bin/>
    -   SetHandler mod_python
    -   PythonHandler mod_python.cgihandler
    -   Options ExecCGI
    -</Directory>
    -
    -# handler propio:
    -#  se ejecuta el archivo myscript.py función handler(req)
    -<Directory /mywebdir>
    -     AddHandler mod_python .py
    -     PythonHandler myscript
    -     PythonDebug On
    -</Directory>
    +
    # handler Publisher:
    +#  se ejecutará cualquier archivo .py del directorio, llamando a la función de la url:
    +#  http://www.mysite.com/hello.py/say  ejecutara el script hello.py, funcion say
    +<Directory /var/www/html/python/>
    +    SetHandler mod_python
    +    PythonHandler mod_python.publisher
    +    PythonDebug On
    +</Directory>
    +
    +# Handler PSP:
    +#  se ejecutará cualquier archivo .psp (código python embebido en texto html)
    +<Directory /var/www/html/psp/>
    +   AddHandler mod_python .psp
    +   PythonHandler mod_python.psp
    +</Directory>
    +
    +# Handler CGI:
    +#  se ejecutará los scripts .py (scripts normales de python) simil linea de comandos
    +<Directory /var/www/cgi-bin/>
    +   SetHandler mod_python
    +   PythonHandler mod_python.cgihandler
    +   Options ExecCGI
    +</Directory>
    +
    +# handler propio:
    +#  se ejecuta el archivo myscript.py función handler(req)
    +<Directory /mywebdir>
    +     AddHandler mod_python .py
    +     PythonHandler myscript
    +     PythonDebug On
    +</Directory>
     

    Para configurar una aplicación wsgi en mod_python:

    -
    SetHandler python-program
    -PythonHandler modpython_gateway::handler
    -PythonOption wsgi.application app::WSGIApp
    -PythonPath "['C:/Archivos de programa/Apache Software Foundation/Apache2.2/htdocs/app'] + sys.path"
    -PythonOption SCRIPT_NAME /app
    +
    SetHandler python-program
    +PythonHandler modpython_gateway::handler
    +PythonOption wsgi.application app::WSGIApp
    +PythonPath "['C:/Archivos de programa/Apache Software Foundation/Apache2.2/htdocs/app'] + sys.path"
    +PythonOption SCRIPT_NAME /app
     

    Descripción:

      @@ -172,15 +172,15 @@

      Web Server Gateway Interface

    Configuración apache + mod_wsgi

    Para usar WSGI directamente desde apache, existe mod_wsgi, que es un módulo mas reciente, totalmente codificado en C para una mejor performance y estabilidad, que simplifica y resuelve las carencias de mod_python:

    Ejemplo 1: ejecutar en el mismo proceso que apache (no independiente, estilo mod_python/php/etc.). En este caso se mapea la url /app al script wsgi app.py:

    -
    WSGIScriptAlias /app /usr/local/apache/app.py
    +
    WSGIScriptAlias /app /usr/local/apache/app.py
     

    Ejemplo 2: ejecutar en un proceso (interprete) independiente con un usuario arbitrario diferente de apache (estilo FastCGI, mejorando seguridad y performance):

    -
    WSGIDaemonProcess site-1 user=trac group=trac threads=25
    -WSGIScriptAlias /site-1 /usr/local/apache/app.py
    -<Directory /usr/local/apache>
    -WSGIProcessGroup site-1
    -WSGIApplicationGroup %{GLOBAL}
    -</Directory>
    +
    WSGIDaemonProcess site-1 user=trac group=trac threads=25
    +WSGIScriptAlias /site-1 /usr/local/apache/app.py
    +<Directory /usr/local/apache>
    +WSGIProcessGroup site-1
    +WSGIApplicationGroup %{GLOBAL}
    +</Directory>
     

    Configuración lighttpd + wsgi

      @@ -189,17 +189,17 @@

      Web Server Gateway Interface

    Ejemplo "avanzado"

    Con respecto a la diferencia con PHP/PSP, la mayoría de las aplicaciones web en python tienen un solo punto de entrada (un solo .py), que funciona como "despachador", dependiendo de que url te piden, se llama a una función o a otra (generalmente se usa la variable de entorno SCRIPT_NAME o similar, o directamente usar cherrypy, django, turbogears, etc., para que ruteen las peticiones a las clases/funciones que correspondan)

    Ejemplo muy simple con WSGI:

    -
    def App(environ, start_response):
    -        "Punto de entrada WSGI"
    -        if environ['SCRIPT_NAME'].endswith("xxxx"):
    -                respuesta_html = xxxx(environ)
    -        elif environ['SCRIPT_NAME'].endswith("yyyy"):
    -                respuesta_html = yyyy(environ)
    -        else:
    -                respuesta_html = "<html><body><p>la url es
    -inválida!</p></body></html>"
    -        start_response ("200 Ok", [('Content-Type','text/html')])
    -        yield respuesta_html
    +
    def App(environ, start_response):
    +        "Punto de entrada WSGI"
    +        if environ['SCRIPT_NAME'].endswith("xxxx"):
    +                respuesta_html = xxxx(environ)
    +        elif environ['SCRIPT_NAME'].endswith("yyyy"):
    +                respuesta_html = yyyy(environ)
    +        else:
    +                respuesta_html = "<html><body><p>la url es
    +inválida!</p></body></html>"
    +        start_response ("200 Ok", [('Content-Type','text/html')])
    +        yield respuesta_html
     

    Entonces, si te llaman www.tuservidor.com/aplicacion/xxxx haces una cosa (xxxx), mientras que si llaman a www.tuservidor.com/aplicacion/yyyy haces otra (yyyy). En comparación con php/psp, sería como llamar a www.tuservidor.com/aplicacion.psp?funcion=xxxx o www.tuservidor.com/aplicacion.psp?funcion=yyyy.

    Esto es un poco mas difícil de entender, pero a la larga es mas flexible porque no te limita a tener un archivo (estructura "física") para cada dirección (estructura "lógica"), limpiando un poco la url de extensiones .py, signos de interrogación, etc. , haciéndolas mas fáciles de entender para el usuario.

    diff --git a/wwwhexactacom/index.html b/wwwhexactacom/index.html index fc768cc4d..62a26fabe 100644 --- a/wwwhexactacom/index.html +++ b/wwwhexactacom/index.html @@ -25,7 +25,7 @@ - + Ir al contenido principal @@ -59,12 +59,12 @@ - +