tag:blogger.com,1999:blog-23792694658593402522024-02-20T23:14:34.038-08:00The Boundingboxhenhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.comBlogger41125tag:blogger.com,1999:blog-2379269465859340252.post-67775520900532583972012-08-11T10:15:00.000-07:002012-08-11T10:15:01.892-07:00Nice Diagram of a Modern Pipeline from Autodesk<a href="http://usa.autodesk.com/adsk/servlet/index?id=16116742&siteID=123112">The link to the Flash Diagram</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHeVKSwGItjo1pVS9zOPgs7wspSJ8sxcH1enNIfhkhFvSdEGNzncU1sOlDVVsr429zI_fI9R-g4MWV3c5xHV_VfF4pPN9ol6SrkJgedUcxLf8JYq-UfMmahgqGeVNZrLq9pqO2dMXHXiw0/s1600/modern_pipeline.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="464" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHeVKSwGItjo1pVS9zOPgs7wspSJ8sxcH1enNIfhkhFvSdEGNzncU1sOlDVVsr429zI_fI9R-g4MWV3c5xHV_VfF4pPN9ol6SrkJgedUcxLf8JYq-UfMmahgqGeVNZrLq9pqO2dMXHXiw0/s640/modern_pipeline.png" width="640" /></a></div>
<br />henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-66618200956514987702012-06-08T00:31:00.005-07:002012-08-12T08:39:38.051-07:00Problema: A qué hora salir de casa para no pillar atasco de camino altrabajo?<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.techbanyan.com/wp-content/uploads/2010/08/china-traffic-jam.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="147" src="http://www.techbanyan.com/wp-content/uploads/2010/08/china-traffic-jam.jpg" width="200" /></a></div>
<h2>
Planteamiento</h2>
<ul>
<li>Tengo la suerte de que la página de la DGT publica las imágenes de trafico de todos las carreteras que uso para llegar al trabajo</li>
<li>La idea es usar estas las imágenes de las cámaras para evaluar el tráfico</li>
<li>La primera parte del proyecto consistirá en guardar las imáges de las cámaras de tráfico de las carreteras por las que paso y luego poderlas visionar de manera que pueda ver fácilmente:<br /><ul><br />
<li>RECOLECTOR DE IMAGENES<br /><ul><br />
<li>Codificar un script que cada 1min haga una captura de las imagenes de la DGT.</li>
<li>Como no se la cadencia de publicación de las imagenes hacer un diff de la imagen capturada con la anterior y si es la misma no la guardamos</li>
<li>Para obtener las imagenes de la DGT voy a usar python, <a href="http://www.daniweb.com/code/snippet216796.html">ejemplo</a></li>
<li>Para guardar la imagen estoy pensando en usar SQLITE y el campo BLOB. Las imagenes son de 240x176 pixeles = 990KB. <a href="http://effbot.org/zone/sqlite-blob.htm">Aquí </a>hay una referencia al campo BLOB de SQLITE. <a href="http://eli.thegreenplace.net/2009/05/29/storing-blobs-in-a-sqlite-db-with-pythonpysqlite/">Ejemplos con python</a>. <a href="http://mornie.org/blog/2007/01/10/Storing-binary-data-in-SQLite/">Otro ejemplo específico de imagenes</a></li>
<li>Implementar un servicio web que devuelva las imágenes por fecha.<br /> <ul>
<li><a href="http://bitbucket.org/david/django-storages/wiki/DatabaseStorage">Ejemplo de como devolver una imagen usando django</a></li>
</ul>
</li>
</ul>
</li>
<br />
<li>VISUALIZADOR DE IMAGENES<a href="http://eli.thegreenplace.net/2009/05/29/storing-blobs-in-a-sqlite-db-with-pythonpysqlite/"></a><br /> <ul>
<li>Puede ser útil …. serializar una imagen con javascript, <a href="http://stackoverflow.com/questions/766137/javascript-canvas-serialization-deserialization">aquí </a>hay un ejemplo usando dataToURL(). <a href="http://stackoverflow.com/questions/934012/get-image-data-in-javascript">Un mejor ejemplo usando un canvas auxiliar MUY BUENO</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>
Implementacion</h2>
<span style="color: #393939; font-family: helvetica,arial,sans-serif; font-size: 14px; line-height: 20px;"> </span><br />
<pre id="clone-url-https" style="border: 0px initial initial; font-family: monospace; font-size: 14px; font-style: inherit; font-weight: inherit; font: normal normal normal 11px/normal 'Bitstream Vera Sans Mono', Monaco, 'Courier New', Courier, monospace; line-height: 14px; margin-bottom: 3px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 3px !important; outline-color: initial; outline-style: initial; outline-width: 0px; padding: 0px !important; vertical-align: baseline;">hg clone <a href="https://albaregar@bitbucket.org/albaregar/trafficjam" style="border: 0px initial initial; color: #2b547d; font-family: inherit; font-size: 14px; font-style: inherit; font-weight: inherit; margin: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding: 0px; text-decoration: none; vertical-align: baseline;">https://albaregar@bitbucket.org/albaregar/trafficjam</a></pre>
<h2>
Servidor de images con Django<br /> </h2>
<ul>
<li>Crear una aplicacion nueva: python manage.py startapp image_server</li>
<li>Para probar añadir al fichero view.py añadir el siguiente método</li>
</ul>
<blockquote>
<pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace;">from django.http import HttpResponse
def get_image_test(request):
filename = 'trafico.jpg'
image_file = open('/home/boundingbox/webapps/rpc/myproject/image_server/%s'%filename,'rb')
file_content = image_file.read()
response = HttpResponse(file_content, mimetype='image/jpeg')
response['Content-Disposition'] = 'inline; filename=%s'%filename
return response</pre>
</blockquote>
<ul>
<li>Para probar añadir al fichero url.py la siguiente línea</li>
</ul>
<blockquote>
<pre>(r'^imageTest/$', 'myproject.image_server.views.get_image_test')
</pre>
</blockquote>
<ul>
<li>Para acceder a la imagen:</li>
</ul>
<blockquote>
<pre>A) http://rpc.boundingbox.es/imageTest/</pre>
</blockquote>
<blockquote>
<div id="_mcePaste">
B)<html><head<title>Test image server</title></head><body><img src="http://rpc.boundingbox.es/imageTest/"></body></html></div>
</blockquote>
<ul>
<li>Probar una función que devuelva una imagen dado el año, mes, dia. Añadir la siguiente linea a url.py</li>
</ul>
<blockquote>
<pre>(r'^imageGet/(?P<year>\d\d)/(?P<month>\d\d)/(?P<day>\d\d)/$','myproject.image_server.views.get_image')</pre>
</blockquote>
<ul>
<li>Añadir la siguiente función a views.py</li>
</ul>
<blockquote>
<pre>def get_image(request, year, month, day):
html = """
<html>
<body>Anio:%s Mes:%s Dia:%s</body>
</html>"""%(year, month, day)</pre>
<br />
<pre> return HttpResponse(html)</pre>
</blockquote>
<ul>
<li>Para comprobar que funciona</li>
</ul>
<blockquote>
<pre>http://rpc.boundingbox.es/imageGet/10/09/20/</pre>
</blockquote>
<h2>
Cómo encontrar las cámaras</h2>
<ol>
<li>Usar la página de la <a href="http://www.dgt.es/portal/informacion_carreteras/camaras_trafico/">DGT</a> para saber en qué carreteras hay cámaras y cúantas hay. El problema es que en esta página las cámaras se identifican por carretera y punto kilométrico lo cual hace un poco difícil situarlas en un mapa</li>
<br />
<li>Usar la página de la <a href="http://www.guiarepsol.com/es_es/home/">guía repsol</a>, la búsqueda por punto kilométrico y activando la capa de cámaras para poder localizar mejor la situación de las cámaras y ver si la cámara nos sirve. Usar el buscador de carreteras</li>
<br />
<li>Usar google maps para sacar la posición GPS</li>
</ol>
<h2>
Cómo servir ficheros css y javascript desde dentro de una aplicación de Django</h2>
Si la eficiencia no es una prioridad existe un modo sencillo que me viene de perlas. <a href="http://twigstechtips.blogspot.com/2009/08/django-how-to-serve-media-files-css.html">Todo viene explicado en este link</a>.henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-67110136267141996792009-12-02T06:27:00.000-08:002012-08-12T09:01:01.576-07:00Planet51 BoxOffice Summary<center>
<script src="http://www.boxofficemojo.com/data/js/moviegross.php?id=planet51.htm&shortgross=0" type="text/javascript"></script></center>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkbyhOGcuFNxdx-tCkpmlM3XiK09YlggF1n9b-3euHY39PNSclySIfDQwGbpDo2JinGn7SrS5VF4a5pP0bRd6doyGyiLOPUperhSUfcEMB1o8oQQ1DqRUsfVFe-fFxSe1qY8X6p_-VpfSe/s1600/boxoffice_summary01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkbyhOGcuFNxdx-tCkpmlM3XiK09YlggF1n9b-3euHY39PNSclySIfDQwGbpDo2JinGn7SrS5VF4a5pP0bRd6doyGyiLOPUperhSUfcEMB1o8oQQ1DqRUsfVFe-fFxSe1qY8X6p_-VpfSe/s1600/boxoffice_summary01.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKL8vKfNL7LXGP6pugWtUB1tLIgx0LOcXYP4GSn59jvqL_kgtsAALMx8kUzKPgYI5XeBVWzK4twg-J3dRFaKOmVmCiXY3sGeKfVepulzXCH_Z_-Az5HiftV4pSabvs5NkE70w-UWgXN1Z-/s1600/boxoffice_summary02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKL8vKfNL7LXGP6pugWtUB1tLIgx0LOcXYP4GSn59jvqL_kgtsAALMx8kUzKPgYI5XeBVWzK4twg-J3dRFaKOmVmCiXY3sGeKfVepulzXCH_Z_-Az5HiftV4pSabvs5NkE70w-UWgXN1Z-/s1600/boxoffice_summary02.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFdEn8-T22gR37LNtNMYmPM92DK9UbkPvx8-kEQBVwGSwRQHkLoCy7LHJL0-AbUGup0n34WybCOQW5rSeNjkHRRUprx2PmJHCAO1p4kr_2PKDvE2oaLcZdDQRUFN8qPHTqgf9jmCTCBJ0_/s1600/boxoffice_summary03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFdEn8-T22gR37LNtNMYmPM92DK9UbkPvx8-kEQBVwGSwRQHkLoCy7LHJL0-AbUGup0n34WybCOQW5rSeNjkHRRUprx2PmJHCAO1p4kr_2PKDvE2oaLcZdDQRUFN8qPHTqgf9jmCTCBJ0_/s1600/boxoffice_summary03.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzotIbU1NE1T7w8uyPnl6kGMwklpLQAdfan7iylThWpOBy1iH2RCqLuR6SzfEWNP4c_OgZalFSSdoi2fmnZhIi9E1tZ4OPrm3RoMLfvGNlpauzncEaL-Lp_GCJPTbY93ziWhJh73LfqeTn/s1600/boxoffice_summary04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzotIbU1NE1T7w8uyPnl6kGMwklpLQAdfan7iylThWpOBy1iH2RCqLuR6SzfEWNP4c_OgZalFSSdoi2fmnZhIi9E1tZ4OPrm3RoMLfvGNlpauzncEaL-Lp_GCJPTbY93ziWhJh73LfqeTn/s1600/boxoffice_summary04.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilnRUFpodFRlMupNKGFlYNIsoDaGnOKK81HPYYSZYezscZCxpeDA11zhN8-wREYsME3trKNnT1gqGtK3qZsZxFt2b4JzWlAeYthLdW07SPuTQDqu3y6BZcUmj48QXyLnQKwbO7cK1T5vpC/s1600/boxoffice_summary05png.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilnRUFpodFRlMupNKGFlYNIsoDaGnOKK81HPYYSZYezscZCxpeDA11zhN8-wREYsME3trKNnT1gqGtK3qZsZxFt2b4JzWlAeYthLdW07SPuTQDqu3y6BZcUmj48QXyLnQKwbO7cK1T5vpC/s1600/boxoffice_summary05png.png" /></a></div>
<br />
<br />henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com2tag:blogger.com,1999:blog-2379269465859340252.post-48410880394606395562009-11-10T10:04:00.001-08:002012-08-12T08:34:01.320-07:00About Planet51 BoxOffice Tracking<h3>
About the Idea</h3>
<br />
The release of the Planet 51 is almost here, Nov 20th 2009. I'm interested in the box office of this movie so I decided to create some charts to to see the evolution of the box office in a visual way.<br />
<br />
To track Planet 51 US Box Office I've gathered some information from <a href="http://www.boxofficemojo.com/">boxofficemojo</a> and I've done some charts to compare Planet 51 against other animation movies. For this purpose I've chosen 3 groups:<br />
<br />
<strong style="font-weight: bold;">Sony Top 5</strong>: The top 5 animation movies with the best US box office distributed by Sony<br />
<div style="padding-left: 30px;">
1. Cloudy with a chance of meatballs<br />2. Open Season<br />3. Monster House<br />4. Surf's Up<br />5. Final Fantasy<br /><br /><strong>Top 5</strong>: The top 5 animation movies with the best US box office</div>
<div style="padding-left: 30px;">
1. Shrek 2<br />2. Finding Nemo<br />3. Shrek The Third<br />4. Up<br />5. Shrek<br /><br /><strong>Top 5 Nov</strong>: The top 5 animation movies released in November</div>
<div style="padding-left: 30px;">
1. The Incredibles<br />2. Monsters Inc<br />3. Toy Story 2<br />4. Happy Feet<br />5. Polar Express</div>
<h3>
About the charts</h3>
<br /><div style="padding-left: 30px;">
1. Weekend Box Office: This chart let you compare weekend box office of Top 5 and Top 5 Nov movies against Planet 51.<br />2. Daily Box Office Normalized to Planet 51 Release Date. This chart let you compare daily box office of Top 5 and Top 5 Nov movies against Planet 51.<br />3. Daily Box Office Normalized to Planet 51 Release Year. This chart let you compare daily box office and release dates of Top 5 and Top 5 Nov movies against Planet 51.</div>
<h3>
Everyone is invited</h3>
<br />Feel free to collaborate, make suggestions, add comments, whatever and whenever.<br />
<br />
<br />henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-46533406973526726152009-06-27T18:51:00.001-07:002012-08-12T09:06:09.897-07:00From C++ to ObjC/Cocoa. Destination iPhone<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOzzHcc0yC-paf_XNwJcWdSJJmw-w-ARIuO7bS_DLW7Y7kL2HdvO5GBPXJ9CwaSIJ7M6sg9fJWqC3lZNhnqFOVPzbFhqhdKHYJShzl9pQCEJwTxyMpU4dnRbWhofDJeXwRotCTM_uHl8aw/s1600/iphone.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOzzHcc0yC-paf_XNwJcWdSJJmw-w-ARIuO7bS_DLW7Y7kL2HdvO5GBPXJ9CwaSIJ7M6sg9fJWqC3lZNhnqFOVPzbFhqhdKHYJShzl9pQCEJwTxyMpU4dnRbWhofDJeXwRotCTM_uHl8aw/s1600/iphone.jpg" /></a></div>
<br />
I'm thinking about developing some applications for iPhone. I've never code anything for Mac, so starting this trip to IPhone, the first stop is ObjC/Cocoa. Here I have collected some information I found useful for C++ programmer to start coding ObjC .<br />
<br />
<a name='more'></a><br />
<h2>
Concepts Translation</h2>
<hr />
In ObjC compare to C++, the basic object oriented programming concepts are called in a different way. I use this easy table to make the translation.<br />
<br />
<table border="1" style="border-collapse: collapse; border-color: blue; border-style: dotted;"><tbody>
<tr><td><strong>C++</strong></td><td><strong>ObjC</strong></td></tr>
<tr><td>Class</td><td>Object</td></tr>
<tr><td>Member function</td><td>Method</td></tr>
<tr><td>Data members</td><td>Instance variables</td></tr>
<tr><td>Constructor</td><td>Initializer</td></tr>
<tr><td>Destructor</td><td>Deallocator</td></tr>
<tr><td>Multiple Inheritance</td><td>Not available :D</td></tr>
<tr><td>Member function call</td><td>Object message</td></tr>
</tbody></table>
<br />
<h2>
Method declaration & Messages</h2>
<hr />
ObjC syntax for methods is based on Smalltalk so there is nothing in common with C++. To show how to send a message to a instance let's suppose I already have an instance MyObject *objectInstance; declared.<br />
<br />
<strong>Declaration / Message</strong><br />
<br />
The following table shows several examples of method declaration and method invocation = messaging<br />
<br />
<table border="1" style="border-collapse: collapse; border-color: blue; border-style: dotted;"><tbody>
<tr><td colspan="2"><span style="color: green;">method: doSomething<br />arguments: 0<br />return value: 0</span></td></tr>
<tr><td>declaration</td><td>messaging</td></tr>
<tr><td><strong>-(void) doSomething;</strong></td><td><strong>[objectInstance doSomething];</strong></td></tr>
<tr><td colspan="2"><span style="color: green;">method: getAnIntetger<br />arguments: 0<br />return value: 1(int) </span></td></tr>
<tr><td>declaration</td><td>messaging</td></tr>
<tr><td><strong>-(int) getAnIntetger;</strong></td><td><strong>int result = [objectInstance getAnInteger];</strong></td></tr>
<tr><td colspan="2"><span style="color: green;">method: setAnInteger<br />arguments: 1(int)<br />return value: 0 </span></td></tr>
<tr><td>declaration</td><td>messaging</td></tr>
<tr><td><strong>-(void) setAnInteger:(int)value;</strong></td><td><strong>[objectInstance setAnInteger:5];</strong></td></tr>
<tr><td colspan="2"><span style="color: green;">method: setAnIntegerAndString<br />arguments:2 (int, string)<br />return value: 0 </span></td></tr>
<tr><td>declaration</td><td>messaging</td></tr>
<tr><td><strong>-(void) setAnIntegerAndString:(int)value withString:(NSString *)string;</strong></td><td><strong>[objectInstance setAnIntegerAndString:5 withString:@"Jurl Jurl"];</strong></td></tr>
</tbody></table>
<br />
If you replace - with + in the declaration, then the instance method becomes a class methods<br />
<h2>
NSObject</h2>
<hr />
When you use ObjC to write code based on the Foundation Framework, NSObject is the superclass that your classes should inherit from . The Foundation Framework, as its name highlights, is the main framework of the Cocoa Lib. <strong>Corollary</strong>: All your classes should inherit from NSObject.<br />
<br />
<strong>Main methods implemented by NSObject</strong><br />
<br />
<table border="1" style="border-collapse: collapse; border-color: blue; border-style: dotted;"><tbody>
<tr><td><strong>-(id) init</strong></td><td>Default constructor</td></tr>
<tr><td><strong>(NSString *) description</strong></td><td>Returns a string with a brief description of the object</td></tr>
<tr><td><strong>(BOOL) isEqual: (id)anObject</strong></td><td>Compare object instances and returns YES if they are the same and NO otherwise</td></tr>
</tbody></table>
<br />
<h2>
Simple Object/Class Declaration</h2>
<hr />
I prefer learning from examples. So from here I will start writing a simple object to show the fundamentals to code classes in ObjC.<br />
<br />
<span style="color: blue;">FILE: MyObject.h</span><br />
<pre>#import <Foundation/Foundation.h>
<strong>@interface MyObject : NSObject </strong>{
<span style="color: green;"> // Declare instance variables</span>
<span style="color: green;"> </span><span style="color: green;">// Basic types allocation is managed by the compiler</span>
int m_value;
<span style="color: green;"> // Class instances are always managed through pointers
// Allocation is a coder responsability</span>
NSString *m_string;
}
<span style="color: green;">// Declare methods</span>
- (int) getValue;
- (void) setValue: (int) value;
- (NSString *) getString;
- (void) setString: (NSString *) string;
<strong> @end</strong></pre>
<br />
<h2>
Simple Object/Class Definition</h2>
<hr />
<span style="color: blue;">FILE: MyObject.m</span><br />
<pre><strong>#import "MyObject.h"</strong>
<strong>@implementation MyObject</strong>
// Define methods
<strong>- (int) getValue</strong>
{
<span style="color: green;"> // Compiler returns this value doing a copy
<span style="color: black;"> return m_value;
}</span></span></pre>
<br />
<pre><strong>- (void) setValue: (int) value</strong>
{
<span style="color: green;"> // Compiler manages the copy of basic types variables</span>
m_value = value;
}
<strong>- (NSString *) getString</strong>
{
<span style="color: green;">// We just return a pointer, not a copy of the class instance</span>
return m_string;
}
<strong>- (void) setString: (NSString *) string</strong>
{
if (string)
{
<span style="color: green;"> // We tell the memory manager we have just finished using m_string instance</span>
[m_string release];
<span style="color: green;"> // We point to the new string and tell the memory manager
// that we are going to use the instance we have receive</span>
m_string = [string retain];
}
}</pre>
<br />
<strong>@end</strong><br />
<h2>
Intializers. Object instance creation</h2>
<hr />
In ObjC, to create an instance of an object, you need explicitly 2 steps:<br />
<ol>
<li>Allocation</li>
<li>Constructor/Initializer</li>
</ol>
<br />
Following code shows who create an object instance. Take a look at the ObjC message nesting syntax.<br />
<strong>MyString *myString = [[MyString alloc] init];</strong><br />
<h2>
Overwritting NSObject init method</h2>
<hr />
To customize your object initialization is as easy as overwriting the init method of NSObject<br />
<pre><span style="color: blue;"><span style="font-family: mceinline;">FILE: MyObject.m (APPEND)</span></span></pre>
<br />
<pre><span style="color: green;">// id is the common type of any NSObject</span>
- (id) init
{
<span style="color: green;">// First init the super class and check everything went OK</span>
if (![super init]) return nil;
<span style="color: green;">// Set initial value</span>
m_value = 75.0f;
<span style="color: green;">// Return instance, self = this</span>
return self;
}</pre>
<br />
<h2>
<strong>Custom initializer with arguments</strong></h2>
<hr />
If you want your own customized initializer, you can do it of course. Let's see how to.<br />
<br />
<span style="color: blue;">FILE: MyObject.h (APPEND)</span><br />
<pre>- (id) initWithString: (NSString*)string;</pre>
<br />
<span style="color: blue;">FILE: MyObject.m (APPEND)</span><br />
<pre><strong>- (id) init</strong>
{
return [self initWithString: [[NSString alloc] initWithFormat:@"defaultTitle"]];
}
<strong>- (id) initWithString: (NSString *)string</strong>
{
if (![super init]) return nil;
m_value = 75.0f;
<span style="color: green;">// Use retain to keep the</span>
m_string = [string retain];
return self;
}</pre>
<br />
<h2>
Understanding Memory Management</h2>
<hr />
The memory management in ObjC is based on reference counting. All NSObjects have a retain counter.<br />
<ol><br />
<li><strong>MyObject *myObject = [MyObject alloc]; </strong><br />//returns an instance with retainCounter =</li>
<li><strong>[myObject retain]; </strong><br />//make retainCounter++, call retain method if you want to keep the instance alive</li>
<br />
<li><strong>[myObject release]; </strong><br />// make retainCounter--, call release method when you have finished using the instance</li>
<br />
<li>When the retainCounter == 0, the dealloc method is called.</li>
</ol>
<br />
First thing required to avoid memory leaks is to implement dealloc method<br />
<br />
<span style="color: blue;">FILE: MyObject.m (APPEND)</span><br />
<pre><strong>-(void) dealloc</strong>
{
[m_string release];
[super dealloc];
}</pre>
<br />
<h2>
AutoRelease</h2>
<hr />
There is another way to avoid memory leaks without taking care of the retain counters. At least in iPhone applications you need to instance an allocation pool. And as far as I know, to do so, you create an NSAutoreleasePool instance during the initialization process. You can use the autorelease message to make the NSAutoreleasePool responsible for deallocating the object instances. Using this feature you do not control when the instance will be deallocated, it will depend on NSAutoreleasePool strategies.<br />
<br />
This technique is NOT recommended for iPhone, because the memory resources of the phone aren't very large and it's a good idea deallocate instances as soon as they are not useful. But there are circumstances where there is no other option. If you want to overwrite NSObject method description, where you need to return an NSString, if you don't want to keep a description string as an instance variable you have to return an autorelease string because you can't release the return value before returning it.<br />
<pre><strong>- (NSString *) description</strong>
{
NSString *result;
result = [[NSString alloc] initWithFormat: @"Just an object to test];
[result autorelease];
<span style="color: #000800;"> // Alternative using class method
// result = [NSString stringWithFormat:@"Just an object to test"];</span>
return result;
}</pre>
<br />
<h2>
References</h2>
<ul>
<li><a href="http://www.boundingbox.es/wp-content/uploads/2009/06/cpp-objc-en.pdf" title="From C++ to Objective-C">C++ to Objective-C</a></li>
<li><a class="answer-hyperlink" href="http://stackoverflow.com/questions/1063229/objective-c-static-class-level-variables/1250088#1250088">Objective C Static Class Level variables</a></li>
</ul>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-88339213260108205322009-01-18T19:35:00.001-08:002012-08-12T09:07:14.440-07:00More on flash charts to see temperatures<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVGY2l1a1Dil2qCFzTjSjbFXtBvkv6ljR9KBBd4L4-vYibR9RznXLgZvsyf-D7lm5bAanLdCWjC9BnMScz4R9_id0lVVLofudcLDt7mxVnyUoyMS9q3GNee0xz-j4LjcG40c0Wa8XTslxk/s1600/chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="100" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVGY2l1a1Dil2qCFzTjSjbFXtBvkv6ljR9KBBd4L4-vYibR9RznXLgZvsyf-D7lm5bAanLdCWjC9BnMScz4R9_id0lVVLofudcLDt7mxVnyUoyMS9q3GNee0xz-j4LjcG40c0Wa8XTslxk/s200/chart.png" width="100" /></a></div>
<span style="font-size: xx-small;"><br /></span>
You never know from where the inspiration will arrive. Doing some banking managements I took a look at one interesting <a href="http://euribor.com.es/">Euribor Web Page</a> and I came across a nice charts with lots of options to be able to explore values along a wide time range. Doing some research I found that the flash chart used belongs to <a href="http://www.amcharts.com/">amCharts</a>. This web offers the use of a wide range of flash charts for free, including the stocks chart, the one that I was interested in.<br />
<a name='more'></a>The stocks chart is a wonderful flash component. You don't need to worry about almost nothing, just create a csv file with the date and the value you want to see per line. The stocks chart will do the hard job for you. Of course you can spend a lot of time exploring all settings but for the simple ones it won't take too much. It gives you more or less the same behaviours of simple <a href="http://oss.oetiker.ch/rrdtool/">RRDTools</a> graphs but being able to do some zooming interactively.<br />
<br />
<span style="font-size: xx-small;"><br /></span><span style="font-size: xx-small;">[kml_flashembed movie="http://boundingbox.homelinux.net/logger/amstock/amstock.swf" height="250" width="560" fvars=" path= http://boundingbox.homelinux.net/logger/data/ ; settings_file= http://boundingbox.homelinux.net/logger/data/settings_2009.xml"/]</span>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com1tag:blogger.com,1999:blog-2379269465859340252.post-69236042034592799732009-01-08T17:05:00.001-08:002012-08-12T09:07:25.011-07:00Conferencia de Ed Catmull. How Pixar Fosters Collective Creativity<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjELAQUl4ZJfWOLIr_LcrFk6YcjdGfndpAxv92FUlsa24c4Hbd18y_UgKk9Lt8-9_f0ji1LrNyLJMI1vfmCZiH2NYxyBcs8YmDvRpUe4WgAH778F3pFckKrk3nxyqQIbYvjyZ5rW7IojUUT/s1600/edcatmull.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjELAQUl4ZJfWOLIr_LcrFk6YcjdGfndpAxv92FUlsa24c4Hbd18y_UgKk9Lt8-9_f0ji1LrNyLJMI1vfmCZiH2NYxyBcs8YmDvRpUe4WgAH778F3pFckKrk3nxyqQIbYvjyZ5rW7IojUUT/s1600/edcatmull.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
Exiten muchos libros, charlas y conferenciantes dedicados a tratar sobre el tema de cómo gestionar equipos y cómo mantenerlos motivados. Después de leer unas cuantas, casi todas tienen algo de dejavù. En mi opinión, esta conferencia de Ed Catmull destaca sobre las demás en 3 aspectos.<br />
<ol><br />
<li>Ed Catmull es el CTO de una empresa de renombre dentro del la producción de películas de animación y resulta que es un sector del que no abunda información de gestión de equipos.</li>
<br />
<li>En esta conferencia la mayoría de los consejos y recetas van acompañadas de una breve descripción sencilla de como ha llegado a esas conclusiones. Como en cualquier problema es muy importante definir las condiciones de contorno para poder aplicar la solución más adecuada. Muchas conferencias no describen el contexto que llevó a las conclusiones que se exponen, obviando gran parte del problema.</li>
<br />
<li>La conclusiones que aporta Ed Catmull sobre los cimientos de Pixar a la hora de gestionar sus equipos, bajo una apariencia de convencionalidad, no lo son. De hecho, creo que aporta ideas muy modernas de gestión, pero sin negar que implica asumir ciertos riesgos para que realmente fragüen. Vamos, que nadie da duros a peseta. Quien no arriesga no gana.</li>
</ol>
<br />
Antes de seguir recomiendo la lectura <a href="https://www.box.com/s/397b264d5021d352634f">Conferencia</a>, pero si no tienes mucho tiempo aquí va mi resumen. <a href="http://www.boundingbox.es/wp-content/uploads/2008/10"></a><br />
<br />
<a name='more'></a><br />
<h3>
A) Introducción</h3>
<br />
Mi intención en este resumen es destacar y sintetizar las ideas que más me han gustado, las relaciones entre ellas, además de alguna que otra opinion personal. Intentaré, dentro de lo posible, avalar las síntesis con recortes de la conferencia.<br />
<h3>
B) Fundamentos</h3>
<br />
<span style="color: green;"><b>"I don’t think our success is largely luck. Rather, I believe our adherence to a set of principles and practices for managing creative talent and risk is responsible" </b></span><br />
<br />
Hasta aquí todo normal, no es la primera vez que oímos e incluso experimentamos que la gestión del equipo humano y los riesgos son la clave para llevar un proyecto empresarial a buen puerto. Sin embargo, aquí, se refiere al personal como el talento creativo, interesante. A lo largo de la conferencia Ed Catmull muestra su profunda convicción en que las personas con talento y creatividad marcan la diferencia entre el éxito y el fracaso.<br />
<br />
<span style="color: green;"><b>"Some basic beliefs: Talent is rare. Management’s job is not to prevent risk but to build the capability to recover when failures occur. It must be safe to tell the truth. We must constantly challenge all of our assumptions and search for the flaws that could destroy our culture"</b></span><br />
<br />
En mi opinión estas líneas, al comienzo de la conferencia, resumen las dos ideas principales de la charla:<br />
<ul><br />
<li>Talento y riesgo responsable van de la mano con el éxito.</li>
<br />
<li>Potenciar el feedback interno real y mantener una búsqueda constante de los puntos flacos para mantenerse con los pies en la tierra.</li>
</ul>
<br />
<h3>
C) <span style="color: green;">"Talent is rare" & "Management’s job is not to prevent risk but to build the capability to recover when failures occur"</span></h3>
<br />
Durante la conferencia el <b>talento y el riesgo tienen una relación simbiotica</b>. En el siguiente párrafo es donde yo creo que Ed Catmull explica parte de esta relación.<br />
<br />
<span style="color: green;">"To act in this fashion, we as executives have to resist our natural tendency to avoid or minimize risks, which, of course, is much easier said than done.[...]. If you want to be original, you have to accept the uncertainty, even when it’s uncomfortable, and have the capability to recover when your organization takes a big risk and fails. What’s the key to being able to recover? Talented people! Contrary to what the studio head asserted at lunch that day, such people are not so easy to find".</span><br />
<br />
Por otro lado, Catmull deja claro que el talento es poco común o infrecuente, y en esta línea plantea dos temáticas muy interesantes:<br />
<ul><br />
<li>Para encontrar <b>talento hay que cultivarlo</b>, es necesario crear el entorno para que se desarrolle y crezca.<span style="color: green;">"What’s equally tough, of course, is getting talented people to work effectively with one another. That takes trust and respect, which we as managers can’t mandate; they must be earned over time. What we can do is construct an environment that nurtures trusting and respectful relationships and unleashes everyone’s creativity."<span style="color: green;">"If we get that right, the result is a vibrant community where talented people are loyal to one another and their collective work, everyone feels that they are part of something extraordinary, and their passion and accomplishments make the community a magnet for talented people coming out of schools or working at other places.[...] I believe that community matters."</span><br /><br />"<span style="color: green;">Our philosophy is: You get great creative people, you bet big on them, you give them enormous leeway and support, and you provide them with an environment in which they can get honest feedback from everyone"</span></span></li>
<br />
<li>Una vez que se ha conseguido un <b>equipo con talento</b>, hay que añadir la dificultadad de conseguir que sean <b>capaces de trabajar de forma eficiente</b>. En los siguientes recortes, mientras Catmull describe las cualidades de un buen director, implicitamente está describiendo como permitir que el talento trabaje en equipo.<span style="color: green;">"What does it take for a director to be a successful leader in this environment? Of course, our directors have to be masters at knowing how to tell a story that will translate into the medium of film. This means that they must have a unifying vision—one that will give coherence to the thousands of ideas that go into a movie—and they must be able to turn that vision into clear directives that the staff can implement."<span style="color: green;">"They must set people up for success by giving them all the information they need to do the job right without telling them how to do it. Each person on a film should be given creative ownership of even the smallest task. "</span><span style="color: green;">"Good directors not only possess strong analytical skills themselves but also can harness the analytical power and life experiences of their staff members. They are superb listeners and strive to understand the thinking behind every suggestion. They appreciate all contributions,regardless of where or from whom they originate, and use the best ones."</span></span></li>
</ul>
<br />
<h3>
D) <span style="color: green;">"It must be safe to tell the truth" & "We must constantly challenge all of our assumptions and search for the flaws that could destroy our culture"</span></h3>
<br />
En mi opinión, Catmull expone que la maquinaría de un estudio son las personas con su talento y con su creatividad al servicio de los objetivos del estudio y como toda maquinaría, esta requiere un mantenimiento. Al contrario que las máquinas las personas evolucionamos, y de la misma manera tienen que evolucionar las labores de mantienimiento de la empresa. Cómo saber qué acciones de mantenimiento hacer en cada momento?<b> </b>Garantizando el<b> </b><b>feedback interno y </b>manteniendo<b> un cierto grado de paranoia</b>, asumiendo que por muy bien que vayan las cosas siempre hay puntos flacos que encontrar y solucionar. Creo que los dos siguientes parrafos no tienen desperdicio, cremita pura.<br />
<br />
<span style="color: green;">"Observing the rise and fall of computer companies during my career has affected me deeply. Many companies put together a phenomenal group of people who produced great products. They had the best engineers, exposure to the needs of customers, access to changing technology, and experienced management. Yet many made decisions at the height of their powers that were stunningly wrongheaded, and they faded into irrelevance. How could really smart people completely miss something so crucial to their survival? I remember asking myself more than once: “If we are ever successful, will we be equally blind?”</span><br />
<br />
<span style="color: green;">Many of the people I knew in those companies that failed were not very introspective. When Pixar became an independent company, I vowed we would be different. I realized that it’s extremely difficult for an organization to analyze itself. It is uncomfortable and hard to be objective. Systematically fighting complacency and uncovering problems when your company is successful have got to be two of the toughest management challenges there are. Clear values, constant communication, routine postmortems, and the regular injection of outsiders who will challenge the status quo aren’t enough. Strong leadership is also essential—to make sure people don’t pay lip service to the values, tune out the communications, game the processes, and automatically discount newcomers’ observations and suggestions.</span>"<br />
<h3>
E) Otras citas destacadas para la reflexión</h3>
<br />
<ul><br />
<li>Sobre la política de comunicación interna.<span style="color: green;"> "Everyone must have the freedom to communicate with anyone.<br />This means recognizing that the decision-making hierarchy and communication structure in organizations are two different things. Members of any department should be able to approach anyone in another department to solve problems without having to go through “proper” channels. It also means that managers need to learn that they don’t always have to be the first to know about something going on in their realm, and it’s OK to walk into a meeting and be surprised. The impulse to tightly control the process is understandable given the complex nature of moviemaking, but problems are almost by definition unforeseen. The most efficient way to deal with numerous problems is to trust people to work out the difficulties directly with each other without having to check for permission."<br /><br />Francamente interesante. En este tema mi pregunta sería si está política de comunicación puede aplicarse a cualquier empresa o si solo es aplicable a empresas con una consolidación y madurez suficiente.</span></li>
<br />
<li>Sobre la calidad<span style="color: green;"> "There has to be one quality bar for every film we produce"</span>En esta cuestión no puedo estar más de acuerdo, creo que es importante establecer un grado de calidad y satisfacción standard, y llevar a cabo los esfuerzos necesarios para conseguirlo. Si no se está dispuesto a estos sacrificios es mejor parar y replantearse las cosas. Pero no se debería bajar y subir el listón según las cirscunstancias.</li>
<br />
<li>Sobre la relación entre la tecnología y el arte<span style="color: green;"> "John coined a saying that captures this dynamic: “Technology inspires art, and art challenges the technology.”"Esto ya es más una cita filosófica que puede quedar muy bien en la firma de un foro o en los emails :).</span></li>
</ul>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com3tag:blogger.com,1999:blog-2379269465859340252.post-33562041506949723732009-01-02T17:32:00.001-08:002012-08-11T20:14:40.165-07:00Debian Server Backup Script using Gmail<a href="http://www.boundingbox.es/wp-content/uploads/2009/01/backup-icon.jpg"><img alt="" class="alignnone size-full wp-image-290" height="65" src="http://www.boundingbox.es/wp-content/uploads/2009/01/backup-icon.jpg" title="backup-icon" width="65" /></a><br />
<br />
The third level in backup security and one of the most important is to be able to store backups in a place different than the production place, well known as <strong>Keep backups off-site</strong>. Currently taking advantage of free services like gmail, it´s much easier to fulfill this third level of backup security and to have all your backups available through an internet connection. Here I show a homemade script that does the following steps.<br />
<ol><br />
<li>Compress your web server, database and svn repository</li>
<li>Encrypt compressed files with openssl</li>
<li>Send those files to a gmail account </li>
<li>Clean gmail account removing old backups</li>
</ol>
<br />
<a name='more'></a><br />
<h2>
1. Shell script for backup compression and encriptation</h2>
<h3>
a) Compression</h3>
This is the simple part. We will backup the SVN repository compressing the repository directory, and we will do the same for the web server, we will compress the www root directory. To backup the Mysql database we will first do a mysqldump and then we will compress the dump file. To configure de compression process we have to define the following variables.<br />
<ul><br />
<li>Backup Path: The path that will be compressed</li>
<br />
<li>Archive Path: The path where we want to store the last backups in your server.</li>
<br />
<li>Backup History: How many backup days you want to keep in your server.</li>
</ul>
<h3>
b) Encriptation</h3>
After having generated the backup files .tgz we will apply openssl encriptation so we can send this files through internet and be almost sure that no one will be able to access them.<br />
<h3>
c) Script code</h3>
<pre style="padding-left: 30px;">#!/bin/bash
# backups
<span style="color: #99cc00;">
</span><span style="color: #99cc00;"># command paths</span>
TAR=/bin/tar
DATE=/bin/date
FIND=/usr/bin/find
ECHO=/bin/echo
MYSQLDUMP=/usr/bin/mysqldump
RM=/bin/rm
OPENSSL=/usr/bin/openssl
PYTHON=/usr/bin/python
SENDGMAIL=/etc/cron.daily/gmailSend.py
CLEANGMAIL=/etc/cron.daily/gmailCleanup.py
<span style="color: #99cc00;"># script variables</span>
DATECODE=`$DATE +%Y%m%d`
ARCHIVEDIR=<span style="color: #ff9900;"><backupArchivePath></span>
BACKUPDIR1=<span style="color: #ff9900;"><webServerPath></span>
ARCHIVE1=$ARCHIVEDIR/$DATECODE-wwwServerBackup.tgz
LOGFILE1=/root/backups/$DATECODE-wwwServerBackup.log
ERRORFILE1=/root/backups/$DATECODE-wwwServerBackup.err.log
BACKUPDIR2=<span style="color: #ff9900;"><subversionPath></span>
ARCHIVE2=$ARCHIVEDIR/$DATECODE-svnBackup.tgz
LOGFILE2=/root/backups/$DATECODE-svnBackup.log
ERRORFILE2=/root/backups/$DATECODE-svnBackup.err.log
BACKUPDIR3=$ARCHIVEDIR/db.sql
ARCHIVE3=$ARCHIVEDIR/$DATECODE-dbBackup.tgz
LOGFILE3=/root/backups/$DATECODE-dbBackup.log
ERRORFILE3=/root/backups/$DATECODE-dbBackup.err.log
<span style="color: #99cc00;">
# Create log and error files if they don't exist and clean them</span>
$ECHO > $LOGFILE1
$ECHO > $ERRORFILE1
$ECHO >> $LOGFILE1
$ECHO >> $ERRORFILE1
$ECHO > $LOGFILE2
$ECHO > $ERRORFILE2
$ECHO >> $LOGFILE2
$ECHO >> $ERRORFILE2
$ECHO > $LOGFILE3
$ECHO > $ERRORFILE3
$ECHO >> $LOGFILE3
$ECHO >> $ERRORFILE3
<span style="color: #99cc00;"># Backup www</span>
$TAR czvf $ARCHIVE1 $BACKUPDIR1 >> $LOGFILE1 2>> $ERRORFILE1
$OPENSSL enc -aes-256-cbc -e -in $ARCHIVE1 -out $ARCHIVE1.enc -pass pass:<span style="color: #ff9900;"><password></span>
$RM $ARCHIVE1
<span style="color: #99cc00;">
# Backup svn repos</span>
$TAR czvf $ARCHIVE2 $BACKUPDIR2 >> $LOGFILE2 2>> $ERRORFILE2
$OPENSSL enc -aes-256-cbc -e -in $ARCHIVE2 -out $ARCHIVE2.enc -pass pass:<span style="color: #ff9900;"><password></span>
$RM $ARCHIVE2
<span style="color: #99cc00;"># Backup database</span>
$MYSQLDUMP -u<span style="color: #ff9900;"><user></span> -p<span style="color: #ff9900;"><password></span> --opt --all-databases > $BACKUPDIR3
$TAR czvf $ARCHIVE3 $BACKUPDIR3 >> $LOGFILE3 2>> $ERRORFILE3
$RM $BACKUPDIR3
$OPENSSL enc -aes-256-cbc -e -in $ARCHIVE3 -out $ARCHIVE3.enc -pass pass:<span style="color: #ff9900;"><password></span>
$RM $ARCHIVE3
<span style="color: #99cc00;">
# Remove files more than 2 day old</span>
$FIND $ARCHIVEDIR -type f -mtime +2 -exec rm -f {} \;
<span style="color: #99cc00;">
# Email files to gmail</span>
$PYTHON $SENDGMAIL $ARCHIVE1.enc
$PYTHON $SENDGMAIL $ARCHIVE2.enc
$PYTHON $SENDGMAIL $ARCHIVE3.enc
$PYTHON $SENDGMAIL $ARCHIVE4.enc
<span style="color: #99cc00;"># Clean gmail account moving all backup emails older than 60 days to the trash folder</span>
$PYTHON $CLEANGMAIL
<span style="color: #99cc00;"># Decript</span><span style="color: #99cc00;"> command
# $OPENSSL enc -aes-256-cbc -d -in $ARCHIVE4.enc -out $ARCHIVE4 -pass pass:<password></span></pre>
<h2>
2. Send the encripted backup files to your gmail account as Drafts</h2>
Using <a href="http://libgmail.sourceforge.net/">libgmail</a> [<span style="color: #cc0000;">sadly this library does not work anymore</span>] makes sending files to a gmail account terribly simple, the only problem you need to face is the attachment file size limitation of the gmail account, that during my develepment process was something around 20MB. To solve this issue, we use the split linux tool to cut big files in 19MB chuncks, and then we email each piece.<br />
<br />
<strong><span style="color: blue;">gmailSend.py</span></strong><br />
<pre style="padding-left: 30px;">import sys, os
import libgmail
import glob
def <span style="color: blue;">sendFile</span>(filename):
accountName = <span style="color: #ff9900;"><account name></span> accountPassw = <span style="color: #ff9900;"><account password></span>
gmailAccount = libgmail.GmailAccount(accountName, accountPassw)
try:
gmailAccount.login()
except libgmail.GmailLoginFailure:
print "\nLogin failed. (Wrong username/password?)"
else:
print "Log in successful.\n"
if gmailAccount.storeFile(filename, label='serverBackup'):
print 'File stored successfully'
else:
print 'Could not store'
def <span style="color: blue;">main</span>(argv):
<span style="color: #99cc00;"># Check file size < 19M</span> if os.path.getsize(argv[1]) <= 19000000:
sendFile(argv[1])
else:
<span style="color: #99cc00;"># Call split -d -b 19000000 argv[1] argv[1]+'.'</span> os.system('split -d -b 19000000 %s %s.'%(argv[1], argv[1]))
<span style="color: #99cc00;"># Call cat file.tgz.00 file.tgz.02 file.tgz.03 > file.tgz to compact splitted files</span>
<span style="color: #99cc00;"># Go throug all files created from the split and send them</span>
filePieces = glob.glob('%s.*'%(argv[1]))
for file in filePieces:
sendFile(file)
if __name__ == '__main__':
main(sys.argv)</pre>
<br />
<h2>
3. Clean gmail account</h2>
After using the script during several months I ended using all the space of my gmail account so I had to do a manual clean up. To avoid this awful task I've added a final cleanup python script, responsible for moving all backup email drafts older than 60 days to the gmail trash folder. As gmail deletes all emails that have been in the trash more than 30 days, we will keep 3 months backup history.<br />
<br />
<strong><span style="color: blue;">gmailCleanup.py</span></strong><br />
<pre style="padding-left: 30px;">import sys, os
import libgmail
import glob
import datetime</pre>
<br />
<pre style="padding-left: 30px;"><span style="color: #99cc00;"># This method parses the subject of the draft mail.
# It supposes that the subject of the email uses the backup script naming conventions
# Subject example: 'FSV_01 20081201-dbBackup.tgz.enc'</span><span style="color: #99cc00;">
</span>
def <span style="color: blue;">ThreadSubject2Datetime</span>(subject):
items = subject.split(' ')
if len(items) == 1:
return None</pre>
<br />
<pre style="padding-left: 30px;"> items = items[1].split('-')
if len(items) == 1:
return None</pre>
<br />
<pre style="padding-left: 30px;"> date = items[0]
return datetime.datetime(int(date[:4]), int(date[4:6]), int(date[6:8]))</pre>
<br />
<pre style="padding-left: 30px;"><span style="color: #99cc00;"># This script will move to the trash all draft emails older than 60 days
# As gmail deletes all email is the trash that have been there for 30 days,
# we will keep 3 months backup history</span>
def <span style="color: blue;">main</span>(argv):
accountName = <span style="color: #ff9900;"><account name></span>
accountPassw = <span style="color: #ff9900;"><account password></span></pre>
<br />
<pre style="padding-left: 30px;"> gmailAccount = libgmail.GmailAccount(accountName, accountPassw)
try:
gmailAccount.login()
except libgmail.GmailLoginFailure:
print "\nLogin failed. (Wrong username/password?)"
else:
folder = gmailAccount.getMessagesByFolder(libgmail.U_DRAFTS_SEARCH, allPages = True)
for thread in folder:
date = ThreadSubject2Datetime(thread.subject)
if date:
if date <= datetime.datetime.today() - datetime.timedelta(60):
gmailAccount.trashThread(thread)</pre>
<br />
<pre style="padding-left: 30px;">if __name__ == '__main__':
main(sys.argv)</pre>
<br />
<h2>
4. Known issues</h2>
<ul>
<li>The gmailCleanup.py script supposes the gmail account is one created only for backup porposes.</li>
<li>I'm sure that the shell script can be improved because I'm not an expert on bash scripting. You can use it as a start with script.</li>
<li>I'm missing the configuration of the cron deamon to execute the shell script whenever you want because I think this is well documented in internet.</li>
<li>Finally I think I should code all the process in python.</li>
</ul>
<h2>
5. Acknowledgments</h2>
Thanks to <a href="http://www.codepixel.com/">Javier Loureiro</a> for the startup ideas around backups and gmail.henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-91992620779232096542009-01-01T15:31:00.001-08:002012-08-11T19:54:32.284-07:00PythonWin 2.4.3 Create wrap classes for COM automation<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHHbo0OLXu07ub2Br9KVz3PBeeciAqOYYscQamUU9_2tKs-2HKcou0Ts6BxhHPp_Qx-hTcBodbwQTsYpS7WSgYGDROj_khfLH7Zo6suBflLiRlu33mmgkItiKhKKEhy1H-WvwyZqwhaBx1/s1600/pythonwin00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHHbo0OLXu07ub2Br9KVz3PBeeciAqOYYscQamUU9_2tKs-2HKcou0Ts6BxhHPp_Qx-hTcBodbwQTsYpS7WSgYGDROj_khfLH7Zo6suBflLiRlu33mmgkItiKhKKEhy1H-WvwyZqwhaBx1/s1600/pythonwin00.png" /></a></div>
<br />
This is just a little tip for those who use python and work with COM automation components. If you are a windows user, and you want to write python scripts to interact with Adobe Photoshop, Microsoft Excel, Microsoft Visual Studio the best way to do so is using the this application's COM componts. But most of the times finding documentation this COM components registered in your Windows is tricky and difficult. Using a simple tool that is automatically installed with the pythonwin module, you can get wrap python classes for all interfaces and constants exported by a registered COM component. This usually helps a lot to find non documented methods, and even to make your python script more legible and clean.<br />
<h3>
<a name='more'></a>Steps to get your wrap classes</h3>
<br />
<div style="padding-left: 30px;">
1. Go to Start->Programs->Python->PythonWin</div>
<br />
<div style="padding-left: 30px;">
2. Menu Tools->COM MakePy utility->Explore and select the registered COM component you want to use.</div>
<br />
<div style="padding-left: 30px;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglBUeEcswAXmFEXxx8qjRb7YNGXzAcSFxlEyGVSnijq7cMnbSEguYAwYtEZFQiMPxgqhEBRhVssJ-78ra8uqjCAd7yQikyvrhzDUev8tLMTd8yLKXQ22UyxHxBQe00_tUxUDslO_Cxj9w6/s1600/pythonwin01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglBUeEcswAXmFEXxx8qjRb7YNGXzAcSFxlEyGVSnijq7cMnbSEguYAwYtEZFQiMPxgqhEBRhVssJ-78ra8uqjCAd7yQikyvrhzDUev8tLMTd8yLKXQ22UyxHxBQe00_tUxUDslO_Cxj9w6/s400/pythonwin01.png" width="400" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhReVQTXiXKyevr7Bbi2APsfI-c5z6FAXAHAUOwXophic2IpQjo6DaQw_h6E-djR_8VMSdpWgLbi81FIMesKkbXYiV84Zh3p5mDEvZJPIeFnNr4VzK19C77cd444bDp69AxJ5DLKsYKOz0d/s1600/pythonwin02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="285" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhReVQTXiXKyevr7Bbi2APsfI-c5z6FAXAHAUOwXophic2IpQjo6DaQw_h6E-djR_8VMSdpWgLbi81FIMesKkbXYiV84Zh3p5mDEvZJPIeFnNr4VzK19C77cd444bDp69AxJ5DLKsYKOz0d/s400/pythonwin02.png" width="400" /></a>
</div>
<br />
<div style="padding-left: 30px;">
3. The main window will show the path file where the python file has been generated</div>
<br />
<div style="padding-left: 30px;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhovIbZE2Sge8fV21ImuDw9D4o90C8lh2yDS3Uqx8VaGZXCFhXfV0eBsuJfcSEEZV11C-tdahjW2zt7oG5RVGNd-bvee4rJdmrBkUP2WvnptH0gKujAZgw9SQ3fWuG8kYPWjrjinvKP8lU_/s1600/pythonwin03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="217" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhovIbZE2Sge8fV21ImuDw9D4o90C8lh2yDS3Uqx8VaGZXCFhXfV0eBsuJfcSEEZV11C-tdahjW2zt7oG5RVGNd-bvee4rJdmrBkUP2WvnptH0gKujAZgw9SQ3fWuG8kYPWjrjinvKP8lU_/s400/pythonwin03.png" width="400" /></a>
</div>
<br />
<div style="padding-left: 30px;">
</div>
<br />
<br />
<h3>
Use case with Adobe Photoshop CS3 Object Library</h3>
<br />
If you don't want to use the wrap classes, you can access the name of the active document and the free memory available of an existing instance of Adobe Photoshop using the following code:<br />
<pre>import win32com.client
cs = win32com.client.Dispatch("Photoshop.Application")
print cs.ActiveDocument.Name
print cs.FreeMemory</pre>
<br />
The other option is to use the PythonWin App to generate the wrap classes of Adobe Photoshop CS3 Object Library and then rename the odd python file name created by PythonWin with the something like this, <strong>adobePhotoshop.py</strong>. Then place this file in a path where your python load modules, for example the same path where you have the file of your main script and then use the following code<br />
<pre>import adobePhotoshop
acs = adobePhotoshop.Application()
print acs.ActiveDocument.Name
print acs.FreeMemory</pre>
<br />
There is not a big improvement compared with the firs option isn't it?. The great advantage arrives when you use the wrap classes file with any python development environment like Eclipse+Pydev. During the development of your script you can use the Outline tool over the <strong>adobePhotoshop.py </strong>and<strong> </strong>explore the methods of any of the interfaces, for example the Application class and all its properties.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLqxEEi3H5EBj04c-Y4TRM24CPYHTe3dKf0g0vwzlhbJpqPQG7yzS_9yDZ5hvF7me2Q9d8I70YxIHd0eFAhDFMcYU_70hCR0MzmbsQczXngNM1yWPZL5bK-Ke3gVuxcbHeHn15g4uzdbDn/s1600/eclipse01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLqxEEi3H5EBj04c-Y4TRM24CPYHTe3dKf0g0vwzlhbJpqPQG7yzS_9yDZ5hvF7me2Q9d8I70YxIHd0eFAhDFMcYU_70hCR0MzmbsQczXngNM1yWPZL5bK-Ke3gVuxcbHeHn15g4uzdbDn/s1600/eclipse01.png" /></a>
<br />
<br />
<div style="text-align: center;">
<strong>Tips to explore the wrap classes file, adobePhotoshop.py</strong></div>
<br />
<strong>1.</strong> Usually for each interface there is a wrap class with the same name, this is an empty class that is usually implemented in a class with the same name but started with underscore. For exampler, to explore the methods of the Application interface look for the implementationt in the class _Application.<br />
<br />
<strong>2.</strong> To explore all data members of one interface explore the implementation of the _prop_map_get_ dictionary of the implementation class. For example, to explore the properties of the Application interface, look for the dictionary _prop_map_get_ of the class _Application.<br />
<br />
<div style="text-align: center;">
<strong>Tip to find the entry point class</strong></div>
<div style="text-align: center;">
<strong><br /></strong></div>
<div style="text-align: left;">
You will be wondering why betewen all those classes I know I have to invoke Application to access photoshop COM. Well it´s easy the entry point classes inherits from CoClassBaseClass.</div>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-69618758684288172942008-08-17T17:02:00.001-07:002012-08-11T19:43:46.968-07:00Inkscape. Vectorize for free and without too much pain<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikZAHWfiogM5aW2i1R0cNV6bLNfCo-ZhJyDbdJBx9cdrMnSHd0FR2pHocFkLmeHF4sH6A_A5_8orQXoyzOCuoDSX1NJpZ5UCzfYwWSFOhojsGtvfmsvuCtL9ixcGp_WmJ7mzzXBIPckZaN/s1600/vectorize.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikZAHWfiogM5aW2i1R0cNV6bLNfCo-ZhJyDbdJBx9cdrMnSHd0FR2pHocFkLmeHF4sH6A_A5_8orQXoyzOCuoDSX1NJpZ5UCzfYwWSFOhojsGtvfmsvuCtL9ixcGp_WmJ7mzzXBIPckZaN/s1600/vectorize.jpg" /></a></div>
<br />
<br />
A great friend and coworker drew my south park caricature. It was a hand drawing so I scanned and get a dirty grey-scale image, not to nice. So to get something cleaner I realized that I will need to vectorize the image. To do so I was looking for some freeware and I found <a href="http://www.inkscape.org/">Inkscape</a>. This open-source software is surprisingly great and the vectorizing tool is awesome for someone like me that was facing this problem for the first time. So in the following lines, I will briefly document how to vectorize a bitmap using <a href="http://www.inkscape.org/">Inkscape</a> and the help of <a href="http://www.gimp.org/">The Gimp</a>.<br />
<a name='more'></a><strong>Vectorizing process</strong><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtrO5rt5yCwmlvvN9Cxrb3KNG4XBjTa1SQm6U61Xp7wQu0mMuzqPJg9L1JTlXa5byxgYBYI7Y_TuUn4DTWIOaAg5_0G6TwZldmo06SCF4iUqlownkgCJKXJCRr0zWKCDxN2eFHqJIM8b83/s1600/vectorize1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="313" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtrO5rt5yCwmlvvN9Cxrb3KNG4XBjTa1SQm6U61Xp7wQu0mMuzqPJg9L1JTlXa5byxgYBYI7Y_TuUn4DTWIOaAg5_0G6TwZldmo06SCF4iUqlownkgCJKXJCRr0zWKCDxN2eFHqJIM8b83/s640/vectorize1.jpg" width="640" /></a></div>
<div style="text-align: center;">
<br /></div>
<ol>
<li>Open the image in The Gimp and select the piece of the image you want to vectorize. Using Ctrl+C and then Ctrl+Shift+V you will create new image and save it (jpg or png will work well).</li>
<br />
<li>Open the Inkscape and Drag&Drop the the new image file into the main window of the Inkscape.</li>
<br />
<li>Select the image and click on menu Path->Trace Bitmap. A pop-up dialog will appear.</li>
<br />
<li>The Trace Bitmap dialog shows several methods to vectorize and a very useful Update button to see a preview of the vectorizing process result. Playing with the parameters for a while will show you all the possibilities.</li>
<br />
<li>When you arrive to a nice result in the preview, you can press OK and the final result will be showed in the main window ready to be edited.</li>
<br />
<li>Usually it's a great idea to select the vectorized result and apply a simplification because the number of knots used for the paths during the vectorization process makes editing the strokes almost impossible. To do so click on menu Path->Simplify. Be careful because this algorithm sometimes simplifies too much, but it's usually easy to solve this issues adding some points where the simplification was too aggressive.</li>
</ol>
<h3>
<strong>Tips</strong></h3>
<ol>
<li>If you have big black shapes, probably the vectorizer will create several white gaps. Increase the Suppress Speckles parameter within the Options tab to remove them.</li>
<br />
<li>Usually the Brightnees cutoff works pretty well, but when the edges of the shapes are well defined by colors use the Color Quantization</li>
</ol>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com2tag:blogger.com,1999:blog-2379269465859340252.post-55580886574667457122008-07-25T16:34:00.001-07:002012-08-12T09:08:31.516-07:00Modelling (II). Playing with subdivision surfaces.<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.boundingbox.es/wp-content/uploads/2008/07/3d1.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" class="alignnone size-medium wp-image-194" height="80" src="http://www.boundingbox.es/wp-content/uploads/2008/07/3d1.png" title="3d1" width="80" /></a></div>
<br />
<br />
The main idea behind modelling using subdivision surfaces is to create simple geometry that after applying a smoothing algorithm like Catmull-Clark or Loop it finally gets its smoothed and final shape. This way you model the low resolution mesh and you get the higher resolution meshes applying different levels of this smoothing modifiers.<br />
<br />
The main problem is that this smoothing algorithms will smooth at all cost and you sometime want to keep several edges chamfered but hard. One way to do this is creating bound edges around the edges you want to be hard.<br />
<a name='more'></a>I'm using 3dsmax as the modeling software and to start playing with this I found the exercise of keeping a box like a box after applying a TurboSmooth a great way of understanding the behavior of the smoothing algorithms<br />
<div style="text-align: center;">
<a href="https://www.box.com/s/c213d42ecdd6280fc9cf"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" height="400" width="500"><param name="src" value="http://www.boundingbox.es/wp-content/uploads/2008/07/limitingsmoothing.swf" /><embed type="application/x-shockwave-flash" width="500" height="400" src="http://www.boundingbox.es/wp-content/uploads/2008/07/limitingsmoothing.swf"></embed></object></a></div>
<div style="text-align: left;">
</div>
<br />
<div style="text-align: left;">
Another a bit more complex example. This time we will create a smoothed gear. Here I show you one strategy</div>
<br />
<br />
<div style="text-align: center;">
<a href="https://www.box.com/s/c213d42ecdd6280fc9cf"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" height="400" width="500"><param name="src" value="http://www.boundingbox.es/wp-content/uploads/2008/07/limitingSmoothing2.swf" /><embed type="application/x-shockwave-flash" width="500" height="400" src="http://www.boundingbox.es/wp-content/uploads/2008/07/limitingSmoothing2.swf"></embed></object></a></div>
<div style="text-align: left;">
</div>
<br />
<br />
<div style="text-align: center;">
Thanks to <a href="http://akenar.com/">Ramón</a></div>
<br />henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-78168708377905419692008-07-18T18:43:00.000-07:002012-08-11T19:18:49.775-07:003dsmax Modelling (I). Using Image references<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: left;">
</div>
<br />
<div style="text-align: left;">
<a href="http://www.boundingbox.es/wp-content/uploads/2008/07/3d1.png"><img alt="" class="alignnone size-medium wp-image-194" height="80" src="http://www.boundingbox.es/wp-content/uploads/2008/07/3d1.png" title="3d1" width="80" /></a></div>
<br />
<div style="text-align: left;">
One interesting technique to model real things, is to use pictures of this real things as a reference and place them in our modelling software so we can do the blocking of the model based on that visual information. Here I will describe step by step how to do it using 3dsmax<strong>. </strong>Thanks to <a href="http://akenar.com/">Ramón</a> for all the help.</div>
<div style="text-align: left;">
</div>
<a name='more'></a><br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<ol style="text-align: left;">
<li>Make 3 photographs from Top, Front and Left sides. Use tripod and avoid as much as posible the perspective deformation</li>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvKEzqtMCmO3yWpii4TGp6yvaFHBGM1rFr1snZ2IoS5RKomAE746tz369EN8IaJ_culY82D1c70HmjMBt83sx0uk0xpPUyncFlPAYougyVqaJiceFg2pKy255jaxfdnOjW_lNg6nacaE_h/s1600/top.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvKEzqtMCmO3yWpii4TGp6yvaFHBGM1rFr1snZ2IoS5RKomAE746tz369EN8IaJ_culY82D1c70HmjMBt83sx0uk0xpPUyncFlPAYougyVqaJiceFg2pKy255jaxfdnOjW_lNg6nacaE_h/s1600/top.jpg" /></a><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE9KwE9UhuMHXZTlhG_JPY72eJ62XY7SEpmqlThJFnqCIe8WeJqfh5j9l2I0W4prgO0Qydl2mhQxJNUnRCDhMbBaUyuPbqH18lvObkrxi2TjEkbxHUkMvZvf4MOOBgEkYmF7c6_ffrDJvb/s1600/front.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE9KwE9UhuMHXZTlhG_JPY72eJ62XY7SEpmqlThJFnqCIe8WeJqfh5j9l2I0W4prgO0Qydl2mhQxJNUnRCDhMbBaUyuPbqH18lvObkrxi2TjEkbxHUkMvZvf4MOOBgEkYmF7c6_ffrDJvb/s1600/front.jpg" /></a><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifqJ-uI1WQ5FlXRPRgqaZU902atew7b47Y8t7djXX4Vu7hyphenhyphenr7rfA2FqcIMn3aOVzDLQ7qDU5gsffR0UpkchQ6Bj5tq4uK5N1_AGjParPG38f4j0W-bSERnp_xI6AOuy0E_rsgtziK_iC9J/s1600/left.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifqJ-uI1WQ5FlXRPRgqaZU902atew7b47Y8t7djXX4Vu7hyphenhyphenr7rfA2FqcIMn3aOVzDLQ7qDU5gsffR0UpkchQ6Bj5tq4uK5N1_AGjParPG38f4j0W-bSERnp_xI6AOuy0E_rsgtziK_iC9J/s1600/left.jpg" /></a><br />
<li>Use The GIMP to crop, cut and paste each of the photos in one big picture, aligning each photo and making them fit.</li>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ_F7AJo1y0k6fu-TEdPvPjBSozR0hgdRZeVt0pkyT0EdBjBDlGm55DTwhVvM7Ah1xVMbV6U7M5OvZkGh0rmQ9RpFVnKgZ9MwcFCkQWbM4Mu84hy2KFJbolin7Gh_DdB5qSngooTzbBfqC/s1600/referencia.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ_F7AJo1y0k6fu-TEdPvPjBSozR0hgdRZeVt0pkyT0EdBjBDlGm55DTwhVvM7Ah1xVMbV6U7M5OvZkGh0rmQ9RpFVnKgZ9MwcFCkQWbM4Mu84hy2KFJbolin7Gh_DdB5qSngooTzbBfqC/s1600/referencia.jpg" /></a><br /><br />
<li>Use guides to match the sides of each view and crop one image per view</li>
<br />
<li>Create a square size image (512x512) and paste the cropped images in the center of the square image, then save it. The square size is important for the 3dsmax viewports to show them properly.</li>
<br />
<li>Finally you have 3 square size images</li>
<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZBK6BVhd_moU_1uizjf2l6PzD6tuTtmDBU39TF0ad_abc8HF7NEmf37G9wbVQRiy0TfQ2wDGfgIyJL5wSSuA1j6Z0uJ5RpBfKOJeq7iL4tEr5tIn6dX5gdoYApeH_i7C6eq11vcWALYf5/s1600/top1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZBK6BVhd_moU_1uizjf2l6PzD6tuTtmDBU39TF0ad_abc8HF7NEmf37G9wbVQRiy0TfQ2wDGfgIyJL5wSSuA1j6Z0uJ5RpBfKOJeq7iL4tEr5tIn6dX5gdoYApeH_i7C6eq11vcWALYf5/s1600/top1.jpg" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiywrRGYlj6LPS_2uXUxKcW5G5Dp-DZFoBTMYE6C5QEPUEoxKZOuVQEcnK_QpDCojI2fFq8tJfUq4yPk4Hu2wxjQqS-pQgaKuJh3-Im9BYS-72D75Dp3xbHZhIxAstiMPEFHezE4M07DTZE/s1600/front1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiywrRGYlj6LPS_2uXUxKcW5G5Dp-DZFoBTMYE6C5QEPUEoxKZOuVQEcnK_QpDCojI2fFq8tJfUq4yPk4Hu2wxjQqS-pQgaKuJh3-Im9BYS-72D75Dp3xbHZhIxAstiMPEFHezE4M07DTZE/s1600/front1.jpg" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfRWoZucTg_1-gt10YfysIxJ4vkr8UuAG9mBDMKnnWmKeoW_bADHVrNYUj9KXUl3TOo47RnRJXjueABEoO-LHEfMfpi9EIrhfzRDv-JbiNI81EeLeRBeoyZZx_ZjLdPfoFdEif8Z6T1wHE/s1600/left1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfRWoZucTg_1-gt10YfysIxJ4vkr8UuAG9mBDMKnnWmKeoW_bADHVrNYUj9KXUl3TOo47RnRJXjueABEoO-LHEfMfpi9EIrhfzRDv-JbiNI81EeLeRBeoyZZx_ZjLdPfoFdEif8Z6T1wHE/s1600/left1.jpg" /></a></ol>
<div style="text-align: left;">
<b>Configuring 3dsmax vewports</b></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<ol style="text-align: left;">
<li>Press Alt+B on each viewport</li>
<li>Elegir el fichero de la imagen y después rellenar las opciones como se muestra en la pantalla</li>
<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNx33gAhrBKL2x4o93gtesuUvtIh-jAc-DHa0KxbfAFLNxxHeP9CA1SzoczzyaKslKorGzL3P_J4QV50-NAi5W9kZ5jf-DZp6NwgWYww5qpyzhNDmGKbRwdMkttsLHmDkxAYzqAba4UNLM/s1600/opciones.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNx33gAhrBKL2x4o93gtesuUvtIh-jAc-DHa0KxbfAFLNxxHeP9CA1SzoczzyaKslKorGzL3P_J4QV50-NAi5W9kZ5jf-DZp6NwgWYww5qpyzhNDmGKbRwdMkttsLHmDkxAYzqAba4UNLM/s400/opciones.jpg" width="323" /></a><br />
<li>Repetir con cada viewport hasta conseguir la siguiente imagen</li>
<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLsrHu9GzbrjkGLleMt6lBi3GhGQy7y_RV4C2BM2Fsq-BlX45OUVEPm9ZnztBZC_sjL-HS7JLde8UwfGBaZAquONBpLLuoQ669gpWAIG4AdOnYpfz3BL_96BOjTuQV4x6I5n1vQEXgQZik/s1600/3dsmax.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="327" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLsrHu9GzbrjkGLleMt6lBi3GhGQy7y_RV4C2BM2Fsq-BlX45OUVEPm9ZnztBZC_sjL-HS7JLde8UwfGBaZAquONBpLLuoQ669gpWAIG4AdOnYpfz3BL_96BOjTuQV4x6I5n1vQEXgQZik/s400/3dsmax.jpg" width="400" /></a>
</ol>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-79699892828653399382008-07-11T17:32:00.000-07:002012-08-11T11:55:52.737-07:00Mundos Digitales 2008 (I). Beowulf y la pirámide del valor.<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI2yiQZwA7yjzowDZkrqV8s8gjcecbvOQxq4B4elqtw59loi2cypoAVupSRDxJl2_zJDn6YIylbfbjk3z9SnVdRn1Kn5oi9VADaVCSWYhnxa5DxTy6BYg5T40AteojN829sZjwXmKv5Faj/s1600/logo_cabecera.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="49" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI2yiQZwA7yjzowDZkrqV8s8gjcecbvOQxq4B4elqtw59loi2cypoAVupSRDxJl2_zJDn6YIylbfbjk3z9SnVdRn1Kn5oi9VADaVCSWYhnxa5DxTy6BYg5T40AteojN829sZjwXmKv5Faj/s320/logo_cabecera.gif" width="320" /></a></div>
<br />
<br />
<br />
<br />
Tuve la suerte de poder asistir a la edición de este año de <a href="http://www.mundosdigitales.org/english/index.htm">MundosDigitales</a>, festival de la industria del 3D que se celebra anualmente en La Coruña y que reune a personas de la mayoría de los estudios de animación nacionales y parte de Europa. Es un encuentro muy agradable donde asistir a conferencias sobre este mundillo y hacer amigos del sector.<br />
<br />
Para no olvidarme de las conferencias que considero que más me han gustado, voy a llevar a cabo unos cuantos post en que describiré varias ponencias de Mundos Digitales 08 de forma desenfadada y con bastantes aportaciones personales (quién avisa no es traidor),<br />
<br />
[Post in spanish because I feel more comfortable using my native language and I don´t have too much time to translate this in english. Content just for spaniards sorry.]<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYHm6w4-rkV65a8SuKyQxaLbuHi_Zxea8xMD8Z0MH_BBVWWWRYJNdggngo22C-GrU3zfa652mHVweHHtQZgAl4Ds2XYpvapYCPRZCqWPsMGsi9t-O5mK2mweGGe-6B90Crmg8b4BuaRn1D/s1600/min_sylwan.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYHm6w4-rkV65a8SuKyQxaLbuHi_Zxea8xMD8Z0MH_BBVWWWRYJNdggngo22C-GrU3zfa652mHVweHHtQZgAl4Ds2XYpvapYCPRZCqWPsMGsi9t-O5mK2mweGGe-6B90Crmg8b4BuaRn1D/s1600/min_sylwan.jpg" /></a></div>
<br />
<br />
<strong><br /></strong>
<strong><br /></strong>
<strong><br /></strong>
<strong>EL CAMBIANTE MUNDO DEL PIPELINE EN EL CINE<br />Sebastian "Beowulf carnosico" Sylwan</strong><br />
<br />
<a name='more'></a><br />
<br />
Y empezaré con una conferencia que sin ser muy técnica me llegó (Qué fuerte!) . Así en breve, este gurú del cine y los efectos nos vino a contar que la industria del 3D está en plena etapa de industralización, justo en ese momento en que se pasa del producto artesanal a la fabricación industrial. De producciones pequeñas en número y de calidad gracias a la dedicación, al mimo y tiempo empleado, a las producciones de grandes tiradas donde la eficiencia y el rendimiento de fabricación permitirán que los contenidos 3D sean más asequibles y sofisticados. Todo esto aderezado con datos, gráficas escaladas (homenaje al Sr.Loureiro) y más datos y más graficas y tal. Que si su predicción se cumple no habrá peli sin VFX y además serán más baratos y se produciran como churros.<br />
<br />
Pero a mi lo que me molo fueron dos grandes conceptos: LA SANTISIMA TRINIDAD y LA PIRAMIDE DEL VALOR<br />
<br />
<strong>LA SANTISIMA TRINIDAD</strong><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJUZjQhsNDlCD6W9C92dQcD4K4Ivct_wLT4hAtwdGRVkJfCoAxaTlJJ1Xp_X1A8_purdp467NR4Ldm9YegeYF0nm3vyVsG_NFn6Si-KfUn9tCpc4MqqcohrO8FZKPrIhRTSdGHF8GpXkdx/s1600/trinidad.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJUZjQhsNDlCD6W9C92dQcD4K4Ivct_wLT4hAtwdGRVkJfCoAxaTlJJ1Xp_X1A8_purdp467NR4Ldm9YegeYF0nm3vyVsG_NFn6Si-KfUn9tCpc4MqqcohrO8FZKPrIhRTSdGHF8GpXkdx/s400/trinidad.png" width="400" /></a></div>
<div style="text-align: center;">
<br /></div>
<br />
<br />
Sebastian no se refirió a este tema ni con este título ni éxactamente con estos nombres, me he permitido la licencia de rebautizarlos para darles un poco más de empaque. En resumen un recordatorio por parte del Sr. Sylwan, de los ingredientes principales para cualquier producción con pretensiones: Poderío Tecnológico, Talento Artístico y Visión Comercial.<br />
<br />
<strong>LA PIRAMIDE DEL VALOR</strong><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfo0Sj5tcQIRjo8rqOk4ExQU2Y_iPC_0jboO7kZkVG74wxNaGCgld8DDmg2Kbjwo-7sGbcMnN0yMMzoZ3vKnaFsyMP-n2GAyLLCovv2o3tfHSKTtnHhmihob_1xu5mqUA6mU-KMcLvdNOY/s1600/piramid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfo0Sj5tcQIRjo8rqOk4ExQU2Y_iPC_0jboO7kZkVG74wxNaGCgld8DDmg2Kbjwo-7sGbcMnN0yMMzoZ3vKnaFsyMP-n2GAyLLCovv2o3tfHSKTtnHhmihob_1xu5mqUA6mU-KMcLvdNOY/s640/piramid.png" width="640" /></a></div>
<br />
Y ahondando en la misma temática pero centrándose en el poder tecnológico, Beowulf nos mostró más conceptos interesantes usando la pirámide del valooorrrr. Aquí podemos ver una propuesta de los cimientos en los que asentar un estudio y lo que deberían aportar a la producción si se usan correctamente. De esta manera:<br />
<ul><br />
<li>El <strong>pipeline </strong>si se está bien diseñando debería aportar <strong>estabilidad </strong>a la producción</li>
<br />
<li>El <strong>software </strong>si se elige bien y se usa correctamente debería aportar <strong>eficiencia </strong>a la producción</li>
<br />
<li>La <strong>fontanería </strong>que era como se refería Sebastian a los desarrollos a media internos, deberían facilitar la <strong>integración </strong>del software en el pipeline de la producción</li>
<br />
<li>Y por último las <strong>diferencias con los competidores</strong> de una producción deberían siempre estar relacionadas con <strong>aspectos innovadores</strong>.</li>
</ul>
<div style="text-align: center;">
<a href="http://www.boundingbox.es/wp-content/uploads/2008/07/piramid.png"><br /></a></div>
<div style="text-align: left;">
En principio ninguno de estos gráficos ni los conceptos que muestran son la pera limonera, pero muchas veces ponerle nombre a las cosas y monstrarlos en una imagen ayuda integrarlos más facilmente y los hace más poderosos. Además son un rato pintones.</div>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-34802982032288389382008-07-09T16:18:00.001-07:002012-08-11T11:57:48.996-07:00MrPotato Indiana Jones<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNSjIzhOJBWu19ilLiKNXfgDlsEOCmPlGI-qOW_0j1Akv_kfzYbdbWpmeYny4k70fWt3nx3dXz-UQgOcSDsszV1Lh3KcjeOrJwnE43XU8bLmBzttjk2Y5Ic5JclMRORzMa5Ij9MDWJUQnC/s1600/mrpotato.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNSjIzhOJBWu19ilLiKNXfgDlsEOCmPlGI-qOW_0j1Akv_kfzYbdbWpmeYny4k70fWt3nx3dXz-UQgOcSDsszV1Lh3KcjeOrJwnE43XU8bLmBzttjk2Y5Ic5JclMRORzMa5Ij9MDWJUQnC/s1600/mrpotato.png" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Incredible, people from Playskool knows what I need, they have already released the new <a href="http://www.amazon.com/Playskool-Potato-Indiana-Jones-Taters/dp/B000Y8Z2L0">MrPotato Indiana Jones</a>, with integrated sound in the hat. So I can get rid of the useless Indiana Jones soundtrack emitter and replace it with my voice synthetizer :D. Now I only need some spare time.<br />
<br />
I agree it´s not very friendly, it´s a kind of ugly, but it´s a MrPotato c´mon and if you press on the hat you will get some music, isn´t it cute?. During this summer holidays I need to be working on that defenitely. MrPotato v.3 is about to come. Muhahahahahenhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-11195305489965502672008-06-07T17:52:00.001-07:002012-08-11T11:19:38.932-07:00Arduino Contest 2008<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/cnxfxr4d12M?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
The company that is currently distributing Arduino in Spain, <a href="http://www.libelium.com/tienda/catalog/index.php">Libelium</a>, organized 2 months ago an <strong>Arduino Contest</strong>. And I force myself to compete with something. I decided to improve my first MrPotato Robot adding voice, led eyes a thermometer, and of course using the new MrPotato Maximus Prime. It took a great effort, I finished the hardware stage, but I couldn't end the software one. Anyway, I sent it to the contest, competing in the Art Hack section.<br />
<a name='more'></a><br />
<br />
Of course I didn't win. I'm sad :( . You can check <a href="http://www.libelium.com/tienda/catalog/contest.php">Libelium contest</a> page to see the winners.<br />
<br />
Here I leave a link to <strong>the guide to create your own</strong> <a href="https://www.box.com/s/2281970055db0cda9225">MrPotato Robot</a>. This link will show you a <strong>mind map</strong>. You can navigate it dragging, zooming and clicking on nodes. When you click on a node it will let you know his child nodes. I'm currently working on a 3D manual, but it will take time.henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-20839272323376103632008-06-07T08:22:00.000-07:002012-06-06T22:39:25.568-07:004 Windows must-have Tools<a href="http://www.boundingbox.es/wp-content/uploads/2008/06/tree.jpg"><img alt="" class="alignnone size-thumbnail wp-image-107" height="48" src="http://www.boundingbox.es/wp-content/uploads/2008/06/tree.jpg" title="tree" width="48" /></a> <a href="http://www.boundingbox.es/wp-content/uploads/2008/06/procmon.png"><img alt="" class="alignnone size-thumbnail wp-image-108" height="48" src="http://www.boundingbox.es/wp-content/uploads/2008/06/procmon.png" title="procmon" width="48" /></a><br />
<br />
Developing SysAdmin task on Windows Operating System seems to be a kind of hard, not anymore if you are properly equiped. Here I recommend a set of cool tools to make your Windows usage&control experience easy peasy.<br />
<ul><br />
<li><b><a href="http://windirstat.info/">Windirstat</a></b></li>
<br />
<li><b><a href="http://technet.microsoft.com/en-us/sysinternals/bb963902.aspx">Autoruns</a></b></li>
<br />
<li><b><a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx">Procmon</a></b></li>
<br />
<li><b><a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx">ProcExplorer</a></b></li>
</ul>
<br />
<a name='more'></a><br />
<br />
<b><a href="http://windirstat.info/">Windirstat</a></b><br />
The perfect tool whenever you do a right click over a folder, select properties and get flashed with the amount of memory contained in the directory, then you start to figure out what the heck am I storing there. Then is when Windirstat comes to the rescue, it will show you in a very intuitive graphic interface which are the folders with more data and the file extensions responsible for the most storage consumption.<br />
<br />
<b><a href="http://technet.microsoft.com/en-us/sysinternals/bb963902.aspx">Autoruns</a></b><br />
There is a time after each windows reinstallation, that you start to notice that it takes ages for windows to give you control after logon. Windows softwares love to install little updaters or checkers or remainders to show up in the taskbar, although you find them useless and annoying but they keep adding more and more. Get rid of those leeches using autoruns.<br />
<br />
<b><a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx">Procmon</a></b><br />
Sometimes you have just two programs opened but your machine behaves lazy, and you don´t know why, then is time to launch Procmon. Firts you will get lost in all the info the Procmon gives you but after you start using the filters you will be able to figure out who is consuming your CPU and your resources. Another nice complement to this tool is the <b><a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx">ProcExplorer</a></b>.henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com3tag:blogger.com,1999:blog-2379269465859340252.post-80245863666398778632008-06-07T07:51:00.001-07:002012-08-11T11:20:56.259-07:00CmdHere. Console directory navigaton... Forget it<a href="http://www.boundingbox.es/wp-content/uploads/2008/06/img_powertoys.gif"><img alt="" class="alignnone size-medium wp-image-106" height="48" src="http://www.boundingbox.es/wp-content/uploads/2008/06/img_powertoys.gif" title="img_powertoys" width="48" /></a><br />
<br />
Some coworker told me that there was a way to navigate your filesystem using the windows explorer and opening a windows console from there. And today I found some time to search the solucion. CmdHere.<br />
<br />
If you are using <strong>Windows Vista</strong>, the CmdHere is a builting feature. The only thing you need to do from your windows explorer is to <strong>Shift+Right Click at the directory</strong> and choose <strong>from the context menu</strong> option <strong>open command prompt here</strong>. For more details, <a href="http://www.maximumpcguides.com/cmdhere-for-windows-vista/">MaximumPcguides</a>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-72343041340334227612008-05-22T11:04:00.000-07:002012-08-11T19:38:14.122-07:00Groupie, groupie!!<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-iCG54P5xcxoxZ68VN44wa_GZVtLZMlKbZQFk6ipHWW-8JhhfCbRVBJ_YvhNB4yXHVRUuJSTcJU9w5hdPCrG8Tqb0067oohkl3ayGe4sAq5ytEKUtmhAH8a3I-WjoVqHUOO3vQVddLIp1/s1600/conchita.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="309" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-iCG54P5xcxoxZ68VN44wa_GZVtLZMlKbZQFk6ipHWW-8JhhfCbRVBJ_YvhNB4yXHVRUuJSTcJU9w5hdPCrG8Tqb0067oohkl3ayGe4sAq5ytEKUtmhAH8a3I-WjoVqHUOO3vQVddLIp1/s320/conchita.jpg" width="320" /></a></div>
<br />
<br />
Let's give this blog a little bit of color. Here I want to share with you my Conchita's Signed CD. A friend of mine, (Mrs. Andrew), has contacts in the VIP world, and gathered this for me. I'm pretty excited, I'm not sure how much time it will last. Anyway here I add a brush of eccentricity to this blog.<br />
<br />
<br />
<br />henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-290693488035048292008-03-22T19:23:00.001-07:002012-08-11T11:46:24.462-07:00FusionCharts. Cool flash charts with a free distribution<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEBmWqAwn6uF4B-1CxG56N6T0fPEXgqUyGEUbT7BqCQ0jTTLxlcI9jmSpUNKT_y8U0e3kfFrMz1wVvUELGteD8RAT4KfZ9rRA8QWlFqN1H_vC4sV37wipwe0DgURIKlK11VWklGXiurimV/s1600/fusionChartsTemperature.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEBmWqAwn6uF4B-1CxG56N6T0fPEXgqUyGEUbT7BqCQ0jTTLxlcI9jmSpUNKT_y8U0e3kfFrMz1wVvUELGteD8RAT4KfZ9rRA8QWlFqN1H_vC4sV37wipwe0DgURIKlK11VWklGXiurimV/s1600/fusionChartsTemperature.png" /></a></div>
<span style="font-size: xx-small;"><br /></span>
<span style="font-size: xx-small;"><br /></span>
<span style="font-size: xx-small;">[kml_flashembed movie="http://www.boundingbox.es/wp-content/uploads/2008/03/fcf_mscolumn2dlinedy.swf" height="300" width="600" fvars=" dataURL= http://www.boundingbox.es/wp-content/uploads/2008/03/temperature_080321.xml ; chartWidth = 600 ; chartHeight = 300"/]</span><br />
<span style="font-size: xx-small;"><a href="https://www.box.com/s/45f08364a299e34e3471">fcf_mscolumn2dlinedy.swf</a>
</span><br />
<span style="font-size: xx-small;"><a href="https://www.box.com/s/cc5a0fe9a4d70a12fe46">temperature_080321.xml</a></span><br />
<br />
I have to admit that I wasn´t very proud of my matplotlib code to represent the temperature values I was gathering with Arduino. It was pretty complex, and too slow. Meanwhile I´ve been facing several issues that requires data representation and searching for alternatives I came across a nice solution, flash charts. I found two projects, one open source, <a href="http://teethgrinder.co.uk/open-flash-chart/index.php">Open Flash Charts</a>, and another commercial, but with a free distribution, <a href="http://www.fusioncharts.com/free/">FusionCharts</a><br />
<br />
<a name='more'></a><br />
<strong>Comparing</strong><br />
<br />
At first I was attracted by <a href="http://teethgrinder.co.uk/open-flash-chart/index.php">OpenFlashChart </a>because it has a python binding and it was open source, soon I realized that this library was to focused on PHP and web developments. The python code was mod_python oriented, and I wanted to create flash charts without requiring a web server. Although I finally could create several charts, there was no way to redirect the default loading folder of the .swf and I couldn´t reproduce several examples such as bar links. May be I wasn´t to inspired to solve those problems but I decided to test the other option.<br />
<br />
On the other hand, I downloaded <a href="http://www.fusioncharts.com/free/">FusionCharts</a>. After following the first examples, I realized that this is a more mature solution. Documentation is great, and all the examples worked properly as expected. I also was happy when a show that all chart requirements I had were provided in the free distribution. The only thing I missed was a python mod to create charts easily, so I started working on it.<br />
<br />
<b><a href="https://www.box.com/s/cea46a8e296f0d3e897b">The code</a></b><br />
<br />
This is just a simple python module with several classes to encapsulate the concepts underneath FusionCharts:<br />
<ul>
<li>DataSetValue: Class responsible for storing a data set value and to be able to render in to XML code as FusionCharts expect it</li>
<li>DataSet: Class responsible for storing dataset attributes and to be able to render in to XML code as FusionCharts expect it</li>
<li>MultipleDataSet: Class responsible for storing a multiple series data set and to be able to render in to XML code as FusionCharts expect it</li>
<li>Chart: Base class for all the charts responsible to implement all the common attributes and methods of all type of charts</li>
<li>SeriesChart: Class responsible for storing Single Series, Multiple Series and Combination Charts attributes and to be able to render in to XML code as FusionCharts expect it</li>
</ul>
Currently, it only support all charts that belongs to the Single Series, Multiple Series and Combination. Just as an example here you can see python code to generate a column2D representation<br />
<br />
<pre><code>
# Single Dataset
hours = ['9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00']
temperatures = [10.0,17.0,18.0,19.0,22.0,21.0,20.0]
temperatureDataSet = DataSet("Temperatures", None, ´ff0000´, hours, temperatures)
singleChart = SeriesChart(
'singleSeriesChartTest',
'Column2D',
700, 300,
temperatureDataSet,
"Temperatures",
"Hours",
"C")
singleChart.SetAttribute('subCaption', '(20/03/2008)')
singleChart.SetAttribute('yAxisMinValue', 5.0)
singleChart.CreateCharHTML()</code></pre>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com1tag:blogger.com,1999:blog-2379269465859340252.post-68614158775728748452008-03-08T15:31:00.003-08:002012-08-11T10:57:31.342-07:00libgmail. Python binding for Google's Gmail service<a href="http://www.boundingbox.es/wp-content/uploads/2008/03/gmail.gif" title="gmail"><img alt="gmail" src="http://www.boundingbox.es/wp-content/uploads/2008/03/gmail.gif" /></a><br />
<br />
I´ve spent some time thinking how to backup the data I´m currently storing in my linux server. First of all, I faced the problem of coding the script to backup and then configuring the cron services to execute it daily. When all was working I had to decide where to put those backup files, because leaving them in the server hard disk wasn´t a solution. So I bought an USB hard disk and from time to time I move the backup files there. I was more or less happy with the solution. But some months ago I talk to a friend and co-worker who was starting to use a gmail account as a backup storage. I thought that was a great idea so I started to find a python library that helps me to send all my backups to my auxiliary gmail account, and I found it, <a href="http://libgmail.sourceforge.net/">libgmail </a>.<br />
<a name='more'></a><br />
<br />
<a href="http://libgmail.sourceforge.net/">libgmail </a>does everything you might want to do with gmail, and it has a nice method to send files. It creates a draft email and attaches the file you want to store in the gmail account. It comes with a nice amount of examples and I´ve tested the storeFile that works great.<br />
<br />
Here is the python script that I use to upload the backup files. It´s almost an example provided by libgmail, with little modifications.<br />
<code><br />import sys<br />import libgmail<br /><br />def main(argv):<br /> accountName = 'yourAccountName'<br /> accountPassw = 'yourPassword'<br /><br /> gmailAccount = libgmail.GmailAccount(accountName, accountPassw)<br /> try:<br /> gmailAccount.login()<br /> except libgmail.GmailLoginFailure:<br /> print "\nLogin failed. (Wrong username/password?)"<br /> else:<br /> print "Log in successful.\n"<br /><br /> if gmailAccount.storeFile(argv[1], label='serverBackup'):<br /> print 'File stored successfully'<br /> else:<br /> print 'Could not store'<br /><br /><br />if __name__ == '__main__':<br /> main(sys.argv)</code>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-89317379829529951082008-03-08T14:47:00.001-08:002012-08-11T10:56:37.079-07:00OOOLIB. Python module to create procedural spreadsheets<a href="http://www.boundingbox.es/wp-content/uploads/2008/03/openofficecalc.png" title="OpenOfficeCalc"><img alt="OpenOfficeCalc" src="http://www.boundingbox.es/wp-content/uploads/2008/03/openofficecalc.png" /></a><br />
<br />
At the beginning of this year I decided to take control of my expenses. To do so, I wanted to automate this annoying task as much as possible, to be aware of my expenses without spending too much time. I started gathering data from my bank using the Norma43 format, then adding this info to a database and so on. After all this, I needed to create reports, and I thought that OpenOffice spreadsheets could be a great place to store them.<br />
<br />
To create your procedural spreadsheets you can use csv(coma separated value) files, but you loose the ability to set format configurations like font color, column width and so on. With the <a href="http://ooolib.sourceforge.net/">ooolib</a>, you can use Python to to create procedural <a href="http://www.openoffice.org/">OpenOffice </a>spreadsheets easily and without pain. It doesn´t support all the format options you have in Calc, but the main ones. Definitely enough for me.henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-16119277361658503832008-01-20T15:43:00.001-08:002012-08-11T10:54:11.054-07:00Tune your iTouch<a href="http://www.boundingbox.es/wp-content/uploads/2008/01/images.jpg" title="ipodtouch"><img alt="ipodtouch" src="http://www.boundingbox.es/wp-content/uploads/2008/01/images.jpg" /></a><br />
<br />
The iTouch as it is after you buy it doesn´t worth the money it cost, but after some work tunning it, this nice device begins to blossom. But keep something in mind, without wifi connection to internet your iTouch won´t evolve.<br />
<a name='more'></a><br />
<br />
<strong>iTouch Firmware</strong><br />
<br />
Currently keep your iTouch firmware on 1.1.1. Although the 1.1.2 is been already jailbreaked, it takes more time to hack it and it does not offer any real improvement. Everything can change with the new 1.1.3 version where the promised cut&paste seems to be implemented. But nowadays I recommend to keep the 1.1.1 firmware. If you have updated your iTouch to a higher version just use iTunes 7.5 to downgrade your firmware. You can check your firmware version on iTunes, selecting the iTouch, then the summary tab, on top of the window you will see a label, software version, that's it.<br />
<br />
<strong>Downgrade your firmware if required</strong><br />
<ul><br />
<li>Download firmware 1.1.1</li>
<li>Backup all your data in the iTouch. Copy the content of the iTouch hard disk</li>
<li>Select your iTouch on iTunes</li>
<li>On the Summury tab, Shift+Click on Restore, you will get a file browser where you can select the the 1.1.1 firmware file</li>
<li>iTunes will guide you through the process, and that's it</li>
</ul>
<br />
<strong>jailbreakme.com</strong><br />
<br />
Now that you have your 1.1.1 firmware, connect your iTouch to the internet through a wifi connections. Then use Safari to reach <a href="http://jailbreakme.com/">jailbreakme.com</a>. There select option to jailbreak your device. This web takes advantage of a Tiff buffer overflow bug or something like that, and they force Safari to load a tiff image that enables them to apply the jailbreak and install the installer application.<br />
<br />
With the installer application already on your iTouch, now your tunning process starts, this application connects to several repositories of free and very useful applications for your iphone. I definitely recommend this installations:<br />
<ul><br />
<li><strong>BSD Subsystem</strong>: The core for most of the applications</li>
<li><strong>OpenSSH</strong>: Allows to secure copy things from/to your iTouch</li>
<li><strong>Term-vt100</strong>: The console</li>
<li><strong>Python</strong>: The scripting language</li>
<li><strong>BossTool</strong>: The partition for software in the iTouch 1.1.1 has 300MB and it's almost full. This tool will move your Applications to the data partition and will create the proper symlinks to keep everything working</li>
<br />
<li><strong>Touch Calendar Fix</strong>: Enables calendar app to add calendar entries.</li>
<li><strong>Erica's utilities</strong>: All of them, I think there are 3 sets, useful command for your Term.</li>
<li><strong>Customize</strong>: Enables configuring all your desktop icons and the bottom tool bar ones</li>
<li><strong>Categories</strong>: Enables you remove icons from the desktop and added to category groups</li>
<li><strong>Lockbox</strong>: Great app to keep your secrets and passwords secured</li>
<li><strong>MobileFinder</strong>: The file browser</li>
<li><strong>MobileTextEdit</strong>: The text editor</li>
<li><strong>PocketMoney</strong>: The application to keep track of your money</li>
<li>SysInfo: Just a mini task administrator</li>
<li><strong>Jiggy Runtime and Jiggy</strong>: A javascript development environment. Makes easier to create simple applications for your iTouch</li>
<li><strong>PDFViewer</strong>: It's still under development but for short pdfs will work properly</li>
</ul>
<br />
<strong>Interesting links to check for applications reviews</strong><br />
<ul>
<li><a href="http://appleiphoneschool.com/">Apple phone school. Good place to be updated</a></li>
<li><a href="http://appsafari.com/top/">App Safari, another web to get more installer sources</a></li>
<li><a href="http://limitededitioniphone.com/windows-guide-to-using-winscp-with-iphone">Use WinSCP to connect to your iTouch</a></li>
<br /></ul>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com1tag:blogger.com,1999:blog-2379269465859340252.post-22441495618503080692007-12-29T15:38:00.001-08:002012-08-11T10:51:57.585-07:00Norma43 bank format parser<a href="http://www.boundingbox.es/wp-content/uploads/2007/12/statement_mini.jpg" title="statement"><img alt="statement" src="http://www.boundingbox.es/wp-content/uploads/2007/12/statement_mini.jpg" /></a><br />
<br />
In Spain, all banks has an unified file format to supply statements of account, this format is known as Norma43. The first version of the format was released May 1982 and it's quite simple to parse. Almost all bank's web supplies Norma43 files with your account info. If you want to process this info, inserted in a database or whatever software treatment, this file can be very helpful. I've implemented a python class that parses this file format and fill in an array with all the registers in the file and its field values.<br />
<ul><br />
<li>Here you can find the<a href="https://www.box.com/s/30fe1a6f66ee4acc3767"> Norma43 file format description</a></li>
<li>Here you can find the <a href="https://www.box.com/s/c64268d58cefd5045706">Norma43 python parser</a>.</li>
</ul>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com2tag:blogger.com,1999:blog-2379269465859340252.post-91324297348040107032007-12-29T15:32:00.001-08:002012-08-11T10:31:26.972-07:00SSH editing & WinSCP<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmiNmKAouH4ocFbVO6JmczctTZW7ePzTsfJFtYBchNuuAWukNGPqucs42EQH8KQ1gN7-8AeR48OHEwmzk4Moxv8H15bTkGNoNlNp8xHy5I45lTEDa_cpXpD7TJtR5jCELhG6vQFNCrBCTj/s1600/admin-ajax.php.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmiNmKAouH4ocFbVO6JmczctTZW7ePzTsfJFtYBchNuuAWukNGPqucs42EQH8KQ1gN7-8AeR48OHEwmzk4Moxv8H15bTkGNoNlNp8xHy5I45lTEDa_cpXpD7TJtR5jCELhG6vQFNCrBCTj/s1600/admin-ajax.php.jpg" /></a></div>
<a href="http://www.boundingbox.es/wp-content/uploads/2007/12/winscp.jpg" title="winscp"><br /></a>
<ol><br />
<li>Do you want to edit files on your remote linux server from your windows desktop using your favorite editor (Crimson Editor may be)? </li>
<li>Have your linux server already an SSH server properly configured?</li>
<li>Is your linux configuration mana low?(WOW addicts will understand this question)</li>
<li>If you have answered YES to all the former questions, this blog entry may be helpful for you.</li>
</ol>
After several internet searches I found that the free software, <a href="http://winscp.net/">WinSCP</a>, the one that I use to copy files from/to linux, currently support this feature for any editor and also works great with Crimson editor, enabling remote editing almost transparently. When you edit a remote file, it opens one temporary file in your local machine and monitors the file status, updating the remote file when any change is detected.<br />
<a name='more'></a><br />
<b>Steps to configure WinScp for remote editing</b><br />
<b>1) Access prefrerences dialog</b><a href="http://www.boundingbox.es/wp-content/uploads/2007/12/preferences.jpg" title="winscp preferences"></a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVsTRIwdbXMrQ5Q3VAhdDTgTuJKOLxfhrnx001g59XzUlorjZqyRTzDlNdAohmJREr_2NuBKBlS8rM_nNwVKZHvAhKTELhgZySPslpf_9ayljXL244R7QK7ueJN9FqSrTXhyphenhyphenA5sW-6D-9y/s1600/preferences.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVsTRIwdbXMrQ5Q3VAhdDTgTuJKOLxfhrnx001g59XzUlorjZqyRTzDlNdAohmJREr_2NuBKBlS8rM_nNwVKZHvAhKTELhgZySPslpf_9ayljXL244R7QK7ueJN9FqSrTXhyphenhyphenA5sW-6D-9y/s1600/preferences.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<b>2) Click on Editors section</b><br />
<a href="http://www.boundingbox.es/wp-content/uploads/2007/12/editors.jpg" title="winscp editors section"></a><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT2ZnfTTCMO-0TNJoFV15skg-eSpGkDZTnZvCWZ1_QZTVutksWZj0zhgZu8i6I4M-UBgUZ5T77rBPvC-JZQ0LHhFcqfWjTL3XloTDxaZ1O16V5TOhhiTNCd19-PUJFcv5ESAgoGJCgqFkB/s1600/editors.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT2ZnfTTCMO-0TNJoFV15skg-eSpGkDZTnZvCWZ1_QZTVutksWZj0zhgZu8i6I4M-UBgUZ5T77rBPvC-JZQ0LHhFcqfWjTL3XloTDxaZ1O16V5TOhhiTNCd19-PUJFcv5ESAgoGJCgqFkB/s1600/editors.jpg" /></a></div>
<br />
<b>3) Add your editor to the list, and update the filter if you want. I
added the cedit.exe (Crimsom Editor executable) and I kept the filter as
generic *.* then I moved the cedit list entry up to the top of the list
to set it as default editor for all files</b><a href="http://www.boundingbox.es/wp-content/uploads/2007/12/addeditor.jpg" title="winscp add editor"></a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXqtH4F1PD_MPvYwZhKyZKM1WCu4E3OceOMoRkj7nq1xIiuro0CxYfIugCcqdvVBkSXg2C2KC_i-GJN6cFsl2RvmSWeFt-Sbk-v51fBKoyvUw-Lz9Iuvu4719zhl95SGJxFl_SbnZVvtBG/s1600/addeditor.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXqtH4F1PD_MPvYwZhKyZKM1WCu4E3OceOMoRkj7nq1xIiuro0CxYfIugCcqdvVBkSXg2C2KC_i-GJN6cFsl2RvmSWeFt-Sbk-v51fBKoyvUw-Lz9Iuvu4719zhl95SGJxFl_SbnZVvtBG/s1600/addeditor.jpg" /></a></div>
<br />
<br />
<b>4) To edit your files just right-click the file on the winscp remote
explorer and your editor will be invoked. Whenever you save your file,
winscp will upload the file to the remote sever</b><br />
<a href="http://www.boundingbox.es/wp-content/uploads/2007/12/edit.jpg" title="winscp edit"></a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho6NYeP7hdtvbiJQx31YT9XbFn8AKdQtPBE54SAzLLc3NWQeXWvHyoZwqlfxSZha0EcKsG5Apo7miXS70EKz8BgW2AqprmMdDEIrh3CUni8VqLNuthG5qqXB7cWN7cTdH98PXfXi7vvfaO/s1600/edit.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho6NYeP7hdtvbiJQx31YT9XbFn8AKdQtPBE54SAzLLc3NWQeXWvHyoZwqlfxSZha0EcKsG5Apo7miXS70EKz8BgW2AqprmMdDEIrh3CUni8VqLNuthG5qqXB7cWN7cTdH98PXfXi7vvfaO/s1600/edit.jpg" /></a></div>
<br />
<b></b>
<ul>
</ul>henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0tag:blogger.com,1999:blog-2379269465859340252.post-76119245648851864462007-11-10T18:14:00.001-08:002012-06-08T00:25:32.839-07:00MtgLife returns<a href="http://www.boundingbox.es/wp-content/uploads/2007/11/scr000015.jpg" title="Main GUI"><img alt="Main GUI" src="http://www.boundingbox.es/wp-content/uploads/2007/11/scr000015.jpg" /></a><br />
<br />
Finally I rescued from backups the code of the MgtLife, a Python application I developed a year or two ago for Symbian. The main purpose of this application is to keep updated the life points of the two opponents of a Magic The Gathering match. This is what I call a freak combo, Magic + CellPhone + PyS60.<br />
<a name='more'></a><b>Main Features</b><br /> <br />
<ul>
<li>Show opponents life points</li>
<li>Use pad keys to easily add or remove life points:<br /> <ol>
<li>Left and Right keys change the opponent selected</li>
<li>Up and Down keys are used to add positive or negative life points</li>
<li>Center key to apply the positive or negative life points to the selected opponent</li>
</ol>
</li>
<li>Use the menu key to choose take a photo of the opponent. This photo will be displayed over the life points counter</li>
<br />
<li>Use the menu key to choose Set Team Name to enter the name of the selected opponent. This name will be displayed over the life points counter</li>
</ul>
<b>About the code</b><br />
<br />
This program is probably more interesting from the point of view of a pys60 programmer. Although it lacks lots of comments, it shows how to deal with:<br /> <br />
<ul>
<li>Back buffer management to avoid flickering when updating the GUI</li>
<li>How to manage a list of images</li>
<li>How to avoid the back light to switch off</li>
<li>How to use the camara input and place it in your GUI</li>
<li>How to implement all these using OOP, may be this HowTo not too sucessfully</li>
</ul>
<b>Installation Process</b><br />
For those who own a Nokia 6600 or similar and doesn't have python installed I made a <a href="https://docs.google.com/open?id=0B0sHxzwrMn9PTWM0bXBfVTRmZzQ" title="mgtLife SIS">mtglife.sis</a> package (Be careful with this, just use it on a Nokia 6600 without python installed). People with a different Nokia cellphone follow next terribly weird steps:<br />
<ol>
<li>Download and install python for your symbian. Check this links: <a href="http://www.forum.nokia.com/info/sw.nokia.com/id/ee447e84-2851-471a-8387-3434345f2eb0/Python_for_S60.html">Nokia Forum</a> and <a href="http://sourceforge.net/projects/pys60">pys60 open source project</a></li>
<li>Download and install miso python library (Nice library to do several hacks like avoid the backlight to turn off). Check <a href="http://pdis.hiit.fi/pdis/download/miso/">miso homepage</a> or just download <a href="https://docs.google.com/open?id=0B0sHxzwrMn9PbmtHSE5lMmdpazQ" title="miso.sis">miso.sis</a></li>
<li>Download <a href="https://docs.google.com/open?id=0B0sHxzwrMn9PTWM0bXBfVTRmZzQ" title="mgtLife code">mgtLife code</a>. You should unzip this on the phone unit where you have python installed (Phone memory or MemCard). If you have python installed in your phone memory card, the process will be as easy as reading that mem card on a PC and unziping the mgtLife.zip directly on it.</li>
<li>To execute the mgtLife, go an execute python console on your cellular, then select run script, and you will find in an entry to my/mtglife.py. Extremely awful I know.</li>
</ol>
<b>Gallery</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbCYQph8pUeLIVzCPiG7zB_70P8z9W4bAxi5gCfEPfeQ7PDEcIGgjJSNEt5K0_vzmNJuc7NtHs7c3vW-6_4JQT2XsMinL5k3YGvRXxDxUuXFZke1k6W6huX_Yor6RBlKdfehY6e-J94dUb/s1600/mtglife001.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbCYQph8pUeLIVzCPiG7zB_70P8z9W4bAxi5gCfEPfeQ7PDEcIGgjJSNEt5K0_vzmNJuc7NtHs7c3vW-6_4JQT2XsMinL5k3YGvRXxDxUuXFZke1k6W6huX_Yor6RBlKdfehY6e-J94dUb/s1600/mtglife001.jpg" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV4yzkbJ6RTeqf4aLGMAney5tW1v1s6dMFFDodjZFbLV5247fpvE3s2QLU0a90lqLhRF7kK9XwS_06dnI_Qw3sstx5SH2rM_yyBDUUvhaJZeKOI3nzi7ecowCZ5GusVv00Zm82g0Asgbuw/s1600/mtglife002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV4yzkbJ6RTeqf4aLGMAney5tW1v1s6dMFFDodjZFbLV5247fpvE3s2QLU0a90lqLhRF7kK9XwS_06dnI_Qw3sstx5SH2rM_yyBDUUvhaJZeKOI3nzi7ecowCZ5GusVv00Zm82g0Asgbuw/s1600/mtglife002.jpg" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVy33SKX-fQsdl7OAUR_bKHCkwU0jgeDqv6VX8qMWM399yF63cNoKglpd52Ri7I6CjabLiy__bj145XHtk0w_1afhYz0Ww5YQZk-d6RMwXuSqX_FNapn3qX3xWnsLBpb45b2T9ppFN3o3y/s1600/mtglife010.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVy33SKX-fQsdl7OAUR_bKHCkwU0jgeDqv6VX8qMWM399yF63cNoKglpd52Ri7I6CjabLiy__bj145XHtk0w_1afhYz0Ww5YQZk-d6RMwXuSqX_FNapn3qX3xWnsLBpb45b2T9ppFN3o3y/s1600/mtglife010.jpg" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhumJvrKbg3lPeCW4GI8f-u4E90Wo9wxLwixZ-BTxw78bCbTpDHPqFZ1NR1oM9xWLsqUpUcYu3wNwXx7Kb8QZUH4bTOxnoGO-rf0FedKYVFqatAQpnVwiQxpmOs8ddgYxvPcBQveHTKgUIT/s1600/mtglife009.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhumJvrKbg3lPeCW4GI8f-u4E90Wo9wxLwixZ-BTxw78bCbTpDHPqFZ1NR1oM9xWLsqUpUcYu3wNwXx7Kb8QZUH4bTOxnoGO-rf0FedKYVFqatAQpnVwiQxpmOs8ddgYxvPcBQveHTKgUIT/s1600/mtglife009.jpg" /></a></div>
<br />
<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTiIWKM4dzrdDmD4euHwRm8Tx3EV1gkT7wL-Q3CbhPc5exKli_DTwCok9a3VnSdnODlzFTZ3rHi21Th4pXX83emQLURpAj-avADQ1xzbGuh04w8K1eRkDdRV7iX_ehyphenhyphenYqYez__Sm3xNFO_/s1600/mtglife016.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTiIWKM4dzrdDmD4euHwRm8Tx3EV1gkT7wL-Q3CbhPc5exKli_DTwCok9a3VnSdnODlzFTZ3rHi21Th4pXX83emQLURpAj-avADQ1xzbGuh04w8K1eRkDdRV7iX_ehyphenhyphenYqYez__Sm3xNFO_/s1600/mtglife016.jpg" /></a></div>
<br />
<br />
<b>Thanks to</b><br />
Thanks to Marcos Martinez who made the GUI designs.henhaochihttp://www.blogger.com/profile/13517573932288687344noreply@blogger.com0