tag:blogger.com,1999:blog-99473472024-03-13T16:35:08.765-03:00Alejandro Santos(\x.x)alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.comBlogger133125tag:blogger.com,1999:blog-9947347.post-42764187875005850322022-01-30T19:23:00.009-03:002022-02-01T09:07:33.421-03:00Como conseguir trabajo de programador sin titulo Universitario<p>{<i>esta es una respuesta mía en el Slack de Arg Tech EU - TechEnEuropa.com sobre la pregunta de cómo conseguir trabajo de tech sin titulo universitario</i>}<br /></p><p>En el Space a lo que apuntaba es como hacer de cero a uno: como hacer para conseguir el
primer trabajo y la primera experiencia laboral sin titulo ni otra
experiencia.</p><p>Teniendo dos o tres años de experiencia ya es fácil
conseguir el numero 4 o 5, pero sino es un Catch 22. Es el meme que
dice.. si no tengo experiencia no puedo tener trabajo, y sin trabajo no
puedo tener experiencia.</p><p>Históricamente, ese loop se rompe con un
titulo o con alguien que tenga confianza que vas a poder crecer. Y ahí
hay un "hack" que muchos hicimos: empezamos a estudiar y estando en
segundo o tercer año nos metemos en una pasantía o trabajo de
principiante. </p><p>Hay muchas empresas que contratan estudiantes de
segundo-tercer año. Y eso hice yo, empece a trabajar en segundo-tercero,
ademas de hacer un montón de cosas por mi cuenta por fuera de la
universidad.</p><p>Por eso hice la aclaración del titulo, y la
respuesta corta es que un titulo es lo mas rápido y eficiente en tiempo y
esfuerzo, mucho mas que mirar videos de YouTube, Udemy, o hacer
proyectos propios de GitHub.</p><p>Y lo digo siendo alguien que me la paso
mirando videos de YouTube, comprando cursos de Udemy y con un GitHub
lleno de proyectos desde hace mas de 20 años. En mi pagina web personal
esta toda mi vida de programación. </p><p>Yo tuve mi titulo mucho después de
tener ya experiencia laboral, pero me llevo varios años de hacer muchos
proyectos personales y estudiar por mi cuenta. Y también aprendí a programar en el colegio, en mi caso aprendí en el primario desde los 11-12 años.</p><p>Se puede perfectamente conseguir un trabajo sin un titulo. Pero todos los consejos tradicionales para buscar trabajo, <b data-stringify-type="bold">no te sirve ninguno</b>.
No podes ir a una búsqueda laboral de RRHH con un CV de autodidacta y
cero experiencia laboral porque no te van a dar ni cinco de atención.<b data-stringify-type="bold"> </b></p><p><b data-stringify-type="bold">Así a grandes rasgos, la estrategia es totalmente diferente.</b> </p><p>Tenes
que salir por tu cuenta a vender tu tiempo y buscar alguien que quiera
trabajar con vos, no como empleado sino como un socio. No digo de hacer
tu propia empresa, pero tampoco es muy alejado. </p><p>Mis primeras
experiencias de programación fueron justamente así, haciendo programas y
proyectos que a mi me interesaban y realmente funcionaban. Los hice para mi propio uso, por mi propia motivación, y sin esperar compensación monetaria a cambio.<br /></p><ol class="p-rich_text_list p-rich_text_list__ordered" data-border="0" data-indent="0" data-stringify-type="ordered-list"><li data-stringify-border="0" data-stringify-indent="0">hice una pagina web - red social, que se hizo bastante popular</li><li data-stringify-border="0" data-stringify-indent="0">fui uno de los programadores del Argentum Online un juego open source Argentino. <a href="https://www.youtube.com/watch?v=cN9bUQmpGZo" rel="nofollow" target="_blank">Mas detalles en este video</a>.<br /></li><li data-stringify-border="0" data-stringify-indent="0">escribía y participaba de foros y listas de discusión</li><li data-stringify-border="0" data-stringify-indent="0">participaba de eventos y reuniones de programadores </li><li data-stringify-border="0" data-stringify-indent="0">tenia una pagina web personal que yo mismo hice! </li></ol><p>En general, el mensaje es mostrar interés genuino y entusiasmo, y mostrar que uno tiene la capacidad tanto de hacer como de aprender. Programar es entender. <br /></p><p><span class="c-mrkdwn__br" data-stringify-type="paragraph-break"></span>Hacer
esto funciona, pero lleva mucho tiempo. Ya dije brevemente en el Space
que estoy en otro grupo donde ayudamos a los que recién empiezan a
aprender y conseguir trabajo. Ya hay al menos dos personas que sin ningún titulo tienen un trabajo, primero hicieron varios proyectos completos por su cuenta y después tuvieron que salir ellos a buscar
alguien que confíe y que los ayude a capacitarse. Al principio no les
pagaban, y ellos a cambio estaban todo el día aprendiendo. </p><p>Pero les llevó más de un año hasta que consiguieron dar el primer pie laboral.<br /></p><p>Las empresas invierten un montón en sus empleados, muchas veces sin darse cuenta. Ya desde el hecho de tener empleados, es una inversión. Pero en Tech pasa todo el tiempo
que sale una nueva versión de X herramienta y la empresa esta obligada a
usarla, y sus empleados estan obligados a actualizarse. Eso es una inversión. </p><p>Ya paso con Cloud, Python 3, Node.js, React, Microservicios, la historia se repite cada un par de años. Cuando recien sale React, hubo un antes y un despues... las empresas que hoy hacen React, cuando recien empezaban ya tenian empleados que trabajaban en HTML, CSS, Angular, pero nadie sabia React. </p><p>Los mismos trabajadores, ya con trabajo y sin experiencia, tuvieron que aprender a usar React, Node, etc. <br /></p><p>Asi a grandes rasgos, el salto de cero a uno es muy
diferente del salto de 3 a 4 o 7 a 8. <b>La primer experiencia
laboral es muy, muy diferente a la numero 7</b>.</p><p>En ese caso particular, al contratar a alguien con cero experiencia laboral,
la empresa se esta corriendo un riesgo muy grande en contratar a alguien
que tal vez no sea lo que ellos necesitan. La empresa no tiene
referencia para medir tus skills. </p><p>Además
siempre esta la pregunta de por que te van a capacitar para que seis meses después
te vayas a otra empresa que paguen mas. <a href="https://news.ycombinator.com/item?id=30137720" rel="nofollow" target="_blank">Ya está ocurriendo y es lo que salió en el articulo hoy</a>.</p>alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-26610054073595627502016-03-06T08:25:00.000-03:002016-03-06T08:25:02.978-03:00Compilers construction resources<br />
<ul>
<li><a href="http://compilers.iecc.com/crenshaw/">Let's Build a Compiler, by Jack Crenshaw.</a></li>
<li><a href="http://www.ethoberon.ethz.ch/books.html">Compiler Construction - Niklaus Wirth (PDF)</a>. </li>
<li><a href="http://matt.might.net/#teaching">Matt Might teachings about compilers.</a></li>
<li><a href="https://www.coursera.org/course/compilers">Compilers at Coursera</a></li>
</ul>
<div>
However, those who wants to be serious about compilers should consider acquiring the books: </div>
<div>
<ul>
<li>Compilers: Principles, Techniques, and Tools. Either 1st or 2nd Edition. I've got the 1st edition from AbeBooks, the basics are still the same today compared to 30 years ago (tokenizer, parser, syntax driven translation, intermediate code generation). </li>
<li>Engineering a Compiler, Second Edition. This one is a good book too, and it talks in more detail about Recursive Descent Parsers, which in practice is what many compilers are doing today (ie, <a href="http://stackoverflow.com/a/6319216/209629">gcc for C++</a>). It is a simple technique, and you can write a RDP by hand easily.</li>
</ul>
<div>
<br /></div>
</div>
alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-6114520882401518632016-02-17T09:07:00.001-03:002016-02-17T09:07:17.017-03:00Dakara Online en una Raspberry Pi 2<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/rPgDU4Y.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/rPgDU4Y.png" height="179" width="320" /> </a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<a href="https://github.com/DakaraOnline/dakara-server">https://github.com/DakaraOnline/dakara-server</a> </div>
alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-6876380613249820732016-01-14T12:24:00.002-03:002016-01-14T12:24:35.772-03:004U1ITU<a data-flickr-embed="true" href="https://www.flickr.com/photos/alejolp/24009046849/in/dateposted-public/" title="IMG_20151024_174838"><img src="https://farm2.staticflickr.com/1673/24009046849_64cf763b3c.jpg" width="500" height="375" alt="IMG_20151024_174838"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-25166365868364711222015-09-14T11:25:00.003-03:002015-09-14T11:27:05.344-03:00tl;dr: Python 2 vs Python 3<blockquote>
<pre>$ cat main.py
print (u"Hello " + b"World!");
$ python2 main.py
Hello World!
$ python3 main.py
Traceback (most recent call ast):
File "main.py", line 1, in <module>
print (u"Hello " + b"World!");
TypeError: Can't convert 'bytes' object to str implicitly
</pre>
</blockquote>
alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com2tag:blogger.com,1999:blog-9947347.post-83736421385503164502015-03-29T11:43:00.003-03:002015-03-29T11:43:57.551-03:00Aprendiendo a programar: eligiendo un lenguajeSi querés aprender a programar y querés elegir un lenguaje, usá uno que te permita aprender los conceptos básicos de programación: Variables, uso de memoria, estructuras de control, flujo de ejecución, expresiones, abstracción, programación modular y reuso de código, recursión, estructuras de datos, algoritmos, eficiencia, programación genérica. Punteros es un tema que todos deberían conocer y estudiar, conocer de su existencia y de su razón.alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-90479735923070851672015-01-19T19:40:00.001-03:002015-01-19T19:47:13.560-03:0012v UPS para Raspbery Pi <a href="https://www.flickr.com/photos/alejolp/16057607572" title="Raspberry Pi UPS by Alejandro Santos, on Flickr"><img alt="Raspberry Pi UPS" height="281" src="https://farm9.staticflickr.com/8592/16057607572_e1c0f02bb2.jpg" width="500" /></a>
<br />
<br />
Andaba necesitando una forma de mantener mi Raspbery Pi funcionando aún con cortes de luz. Mi circuito <a href="http://mresoftware.com/ups_12V.htm">está basado en este otro regulador de MRE</a> con la diferencia que lo armé con lo que tenía en mi caja de herramientas. Los materiales son:<br />
<br />
<ul>
<li>Batería de gel de 12v 7Ah</li>
<li>Cargador de batería de 12v de flote, 1A.</li>
<li>Regulador 5V switching <span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">(¡una joyita!)</span></li>
<ul>
<li><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">RECOM R-78B5.0-1.0: <a href="http://uk.farnell.com/webapp/wcs/stores/servlet/Search?catalogId=15001&langId=44&storeId=10151&categoryId=700000004424&pageSize=25&beginIndex=1&showResults=true&pf=111784521">en Farnell</a></span></li>
<li><span style="color: #222222; font-family: Arial, Helvetica, sans-serif;"><span style="background-color: white; font-size: 13px;"><a href="http://www.adafruit.com/products/1065">TSR12450 en Ada Fruit</a></span></span></li>
</ul>
<li><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">Raspberry Pi</span></li>
<li><span style="color: #222222; font-family: Arial, Helvetica, sans-serif;"><span style="background-color: white; font-size: 13px;">Relés, Op Amps, resistencias, transistor, etc.</span></span></li>
</ul>
<div>
<span style="color: #222222; font-family: Arial, Helvetica, sans-serif;"><span style="font-size: 13px;">La idea del circuito es muy simple: conmutar entre 12v de un transformador y 12v de una batería de gel en el momento en que el transformador pierde energía. Para esto usamos el circuito de MRE que con un op-amp en modo comparador contra un diodo zener abre o cierra los relés.</span></span></div>
<div>
<span style="color: #222222; font-family: Arial, Helvetica, sans-serif;"><span style="font-size: 13px;"><br /></span></span></div>
<div>
<span style="color: #222222; font-family: Arial, Helvetica, sans-serif;"><span style="font-size: 13px;">La primer modificación importante al circuito de MRE es reemplazar el diodo zener con un </span></span><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">LM336Z-5.0 que, a diferencia de un zener, el LM336Z es un integrado para usar como referencia de voltaje, por ejemplo en un instrumento de medifición. </span></div>
<div>
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;"><br /></span></div>
<div>
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">Este integrado es el mismo recomendado por XQ2FOD <a href="http://ludens.cl/Electron/solarreg/Solarr~1.htm">en su circuito de regulación de energía solar</a> (muy interesante y vale la pena leerlo), y los que lean con atención verán que tanto el circuito de MRE como de XQ2FOD funcionan con el mismo principio: un op-amp como comparador de tensión.</span></div>
<div>
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;"><br /></span></div>
<div>
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">Mi primer circuito no tenía un comparador de </span><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">tensión</span><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">, sino que se conectaban los 12v del transformador directo a los relés. El problema con hacer esto es que los relés necesitan mucha menos corriente que el regulador de 5V, y permanecían cerrados durante un segundo de más, por lo que la Rasperry Pi se reiniciaba. </span></div>
<div>
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;"><br /></span></div>
<div>
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">El comparador de tensión lo que hace entonces es cortar los relés antes que la tensión caiga por debajo de lo que el regulador de 5V necesita; esto se ajusta manualmente con el preset de 100k R1. Hice la prueba de cortar intermitentemente la tensión de los 12v del transformador y la Raspberry Pi nunca se reinició.</span></div>
<div>
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;"><br /></span></div>
<div>
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">Otra diferencia con el circuito de MRE es que mi circuito usa dos relés en lugar de uno. El primer relé conmuta entre los 12v del transformador de 220v-12v, y el segundo conmuta el cargador de batería hacia la batería cuando hay 220v en la línea. El segundo relé existe para que el cargador no esté conectado a la batería al momento de cortarse los 220v de línea.</span><br />
<br /></div>
<div>
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">El componente importante y final es el regulador switching de 5V. De mi parte usé el </span><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px; line-height: 18.2000007629395px;">RECOM R-78B5.0-1.0 que posee una de conversión eficiencia del 97%, por lo que a diferencia del clásico regulador lineal 7805 no necesita disipador de calor: a 12v 1A el 7805 posee una eficiencia del ~45%.</span></div>
<div>
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13px;"><br /></span></div>
<div>
<br /></div>
alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com3tag:blogger.com,1999:blog-9947347.post-4822237998486130622015-01-08T15:52:00.001-03:002015-01-08T15:52:11.832-03:00oggdec lame pipe: converting ogg to mp3If this command shows "Warning: unsupported audio format":<br />
<blockquote class="tr_bq">
oggdec -o - file.ogg | lame - file.mp3</blockquote>
Try using raw mode:<br />
<blockquote class="tr_bq">
oggdec -R -o - file.ogg | lame -r - file.mp3</blockquote>
Or, if the generated mp3 file is pure noise, swap the bytes with -x:<br />
<blockquote class="tr_bq">
oggdec -R -o - file.ogg | lame -rx - file.mp3</blockquote>
To convert a batch of multiple ogg files:<br />
<blockquote class="tr_bq">
for x in *.ogg; do oggdec -R -o - "$x" | lame -rxh - "$x.mp3"; done</blockquote>
alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-54202353376105975572014-07-02T07:11:00.001-03:002014-07-02T07:12:04.306-03:00Shut up and calculate!<iframe src="https://www.flickr.com/photos/alejolp/13067838433/player/" width="500" height="331" frameborder="0" allowfullscreen webkitallowfullscreen mozallowfullscreen oallowfullscreen msallowfullscreen></iframe>alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-70612285951596151162014-06-26T06:43:00.004-03:002014-06-26T09:28:03.422-03:00Eclipse Luna on Debian Wheezy Crash<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-p8_XzUGWVvA/U6vq8E3g0TI/AAAAAAAAD3g/c2Zk0dh2vHg/s1600/Solar_eclipse_1999_4_NR.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-p8_XzUGWVvA/U6vq8E3g0TI/AAAAAAAAD3g/c2Zk0dh2vHg/s1600/Solar_eclipse_1999_4_NR.jpg" /></a></div>
<br />
The crash is related to a version mismatch between GTK2, GTK3 and Debian's GLIBC. The relevant bug is here: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=430736">https://bugs.eclipse.org/bugs/show_bug.cgi?id=430736</a><br />
<br />
To force the use of GTK2 on Eclipse Luna you can try:<br />
<blockquote class="tr_bq">
$ export SWT_GTK3=0</blockquote>
For a more permanent solution you can set the GTK version on the eclipse.ini file:<br />
<blockquote class="tr_bq">
--launcher.GTK_version<br />2</blockquote>
This option should be inserted <b>before</b> the --launcher.appendVmargs option.<br />
<br />
And now you should be able to use Eclipse Luna on Wheezy.alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-79747815873243333262014-05-04T17:49:00.000-03:002014-05-04T17:52:06.088-03:00Substring matching in Python (run between naive, Boyer-Moore, and Suffix Array)A few days ago I found this very interesting problem: given a list of strings L, write a function that returns the elements of L which contains some substring S.<br />
<br />
For example, given L=["Casa", "Perro", "Gato", "Onomatopeya", "internacionalizacion", "Om nom nom"] and S="nom", we want the result of find(L, S) = ['Onomatopeya', 'Om nom nom'].<br />
<h2>
Naïve Version</h2>
On Python this sounds simple enough, and we can write:<br />
<blockquote class="tr_bq">
def find1(L, S):<br />
return [x for x in (L) if S in x]</blockquote>
<div>
However, for a big enough L and S we can see the runtime of this function depends not only on the size of L but also on the size of S. That's it, the runtime complexity of find1 in BigOh notation is: O(n.m.s), where:</div>
<div>
<ul>
<li>n=len(L)</li>
<li>m=max([len(x) for x in L])</li>
<li>s=len(S)</li>
</ul>
<div>
The plot of time for find1 for a fixed L and where we increase the size of S looks like this:</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-1gsxm5i_qK4/U2aXz6KsgqI/AAAAAAAADzs/6pA2UL6OQbg/s1600/ik4opAZ.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-1gsxm5i_qK4/U2aXz6KsgqI/AAAAAAAADzs/6pA2UL6OQbg/s1600/ik4opAZ.png" height="159" width="320" /></a></div>
<div>
<br /></div>
<h2>
Boyer-Moore-Horspool</h2>
<div>
It turns out that since version 2.5, Python's "in" operator is implemented internally using a modified version of <a href="http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm">Boyer-Moore algorithm</a> for substring searching. The <a href="http://effbot.org/zone/stringlib.htm">details are here</a>.</div>
<div>
<br /></div>
<div>
We can take advantage of this detail by creating a temporary structure for faster lookups. We pre-process L so we can make fast queries.</div>
<div>
<br /></div>
The idea is to construct a big string W with the concatenation of all the elements of L, using a special char as separator, a char that is not present on S nor any element of L. For example:<br />
<blockquote class="tr_bq">
L = ["Casa", "Perro", "Gato", ...]<br />
W = "Casa\nPerro\nGato\n..."</blockquote>
<div>
Then, finding if a substring S is present in any of the elements of L can be answered by just writing: </div>
<div>
<blockquote class="tr_bq">
S in W</blockquote>
This allows us to answer whether a substring is present or not. To actually construct the resulting list of elements of L which contain S we need another helper structure. We build T, a list of integers that, for every elements in L, equals the starting index of this element in W. Continuing with the example:<br />
<blockquote class="tr_bq">
T = [0, 5, 11, 16, ... ]</blockquote>
</div>
<div>
<div>
This means the first element, "Casa", starts at index 0 in W; the second element "Perro" starts at index 5 in W, etc. And this structure allows us to quickly determine the index in W for every element in, and we lookup the index by doing a binary search on T.</div>
</div>
<div>
<br /></div>
<div>
The runtime complexity for constructing this intermediate index is O(n), with O(n) memory usage.</div>
<div>
<br /></div>
<div>
Our new find function should then:</div>
<div>
<ul>
<li>find the first position of S in W as p</li>
<li>determine for which element of L this index relates to, by doing a binary search on T</li>
<li>from p+1 onwards, find again the next S in W.</li>
</ul>
<div>
Since an element of L can contain many times the same substring S we may jump to the next word on W.</div>
</div>
<div>
<br /></div>
<div>
On code, the find2 function looks like:</div>
<div>
<blockquote class="tr_bq">
def find2(L, S):<br />
# Using the native Boyer-Moore implementation of the "in" operator<br />
R = []<br />
i = W.find(S)<br />
while i != -1:<br />
p = bisect.bisect_right(T, i) - 1<br />
e = L[p]<br />
#assert S in e<br />
R.append(e)<br />
i = W.find(S, T[p] + len(e))<br />
return R</blockquote>
</div>
<div>
The runtime complexity of this new find function is: O(n.m). We still need to take into account the length of each element of L since BMH algorithm is (mostly) linear on the W string. </div>
<div>
<br /></div>
<div>
The plot of runtime for find1 vs. find2 looks like the following graphic. Again, we are leaving a fixed L and increasing the size of S:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-AthevB0oWmc/U2adyD1lheI/AAAAAAAADz8/QZBRix_iSHc/s1600/qqqq.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-AthevB0oWmc/U2adyD1lheI/AAAAAAAADz8/QZBRix_iSHc/s1600/qqqq.png" height="166" width="320" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<h2>
Suffix Array</h2>
<div>
There is a third way to solve this problem, by means of constructing a <a href="http://en.wikipedia.org/wiki/Suffix_array">suffix array</a>. </div>
<div>
<br /></div>
<div>
This amazing data structure offers a runtime complexity of O(log N) for suffix lookups, where N is the length of the string. Incidentally, it also allows to lookup for substrings, since we just lookup until a suffix on the SA has S as prefix.</div>
<div>
<br /></div>
<div>
Again, we need to construct an intermediate index, which is again very simple: sort all the possible suffixes on W. The trick is how to do it: we shall not keep every possible suffix as an string, but just a list of starting positions for every suffix, and sort this list by the actual string of the suffix.</div>
<div>
<br /></div>
<div>
In code, the construction of the SA table is really simple:</div>
<div>
<blockquote class="tr_bq">
# Suffix Array Table<br />
SL = list(range(len(W)))<br />
SL.sort(key=lambda x: W[x:x+100])</blockquote>
</div>
<div>
<div>
The runtime complexity for constructing this intermediate index is O(n.log n), with O(n) memory usage.</div>
</div>
<div>
<br /></div>
<div>
To find a specific suffix we should binary search the SA table, using the element on SL to determine where in W the suffix starts.</div>
<div>
<br /></div>
<div>
Since a substring may appear many times on many elements of S, we may have many sufixes starting with S. The good news is, since the list of suffixes is sorted, all this suffixes will be one after another on the SL table. But since we are doing a binary search on the list of suffixes, we can't be sure on where the middle pointer will jump in this contiguous sequence of suffixes, all starting with S. </div>
<div>
<br /></div>
<div>
Therefore, when we find the position of some suffix we should go back a little to make sure we are starting on the first suffix on the sequence of suffixes that start with S.</div>
<div>
<br /></div>
<div>
On code, our new find3 function looks like:</div>
<div>
<blockquote class="tr_bq">
def find3(L, S):<br />
# Suffix array<br />
start = 0<br />
end = len(SL)<br />
while start < end:<br />
mid = start + (end - start) // 2<br />
pa = SL_key_fn(W, SL[mid], 100)<br />
pb = SL_key_fn(S, 0, len(S))<br />
if pa < pb:<br />
start = mid + 1<br />
elif pb < pa:<br />
end = mid<br />
else:<br />
# A word may contain the same S multiple times<br />
R = set()<br />
while mid > 0 and W.startswith(S, SL[mid]):<br />
mid = mid - 1<br />
if not W.startswith(S, SL[mid]):<br />
mid = mid + 1<br />
while mid < len(SL) and W.startswith(S, SL[mid]):<br />
p = bisect.bisect_right(T, SL[mid]) - 1<br />
e = L[p]<br />
assert S in e<br />
R.add(p)<br />
mid = mid + 1<br />
return [(L[i]) for i in R]<br />
return []</blockquote>
</div>
<div>
The SL_key_fn function was a failed experiment to enhance the performance of the lookups. This function today is:</div>
<div>
<blockquote class="tr_bq">
def SL_key_fn(data, x, llen):<br />
return data[x:x+llen]</blockquote>
</div>
<div>
Which is the same as the key on the SA table sorter.</div>
<div>
<br /></div>
<div>
The runtime performance of the find3 function is: O(log (n.m)), and the plot of the three functions looks like this:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-4cNEkuyRnRE/U2akvsfZS_I/AAAAAAAAD0M/4qFy5N_aIiY/s1600/qqqq3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-4cNEkuyRnRE/U2akvsfZS_I/AAAAAAAAD0M/4qFy5N_aIiY/s1600/qqqq3.png" height="182" width="320" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<h3>
Drawbacks</h3>
<div>
This SA implementation in Python is using a lot of temporary memory for sorting the table. My implementation on my laptop is using 2.4GB of RAM to sort an L of 150k elements. There's been some discussion about this memory issue <a href="http://algorithmicalley.com/archive/2013/06/30/suffix-arrays.aspx">on this blog post</a> and in <a href="http://stackoverflow.com/q/21212815/209629">this Stack Overflow question</a>.</div>
<h2>
Special thanks</h2>
<div>
<a href="http://python.org.ar/">Python Argentina community</a> is a great place to look for help for all your spanish Python programming needs. </div>
<div>
<br /></div>
alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-3883944825884274642014-05-04T06:15:00.001-03:002014-05-04T06:15:15.467-03:00Carpintería de fin de semana<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-MzakeUb53ro/U2YE8a-fC0I/AAAAAAAADzM/OJBLp8Ufdqs/s1600/10259825_10203956672696118_5609483866570389513_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-MzakeUb53ro/U2YE8a-fC0I/AAAAAAAADzM/OJBLp8Ufdqs/s1600/10259825_10203956672696118_5609483866570389513_n.jpg" height="180" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Oiwiuat8P_A/U2YFA5PFp-I/AAAAAAAADzU/zvaAqVdcGCU/s1600/1499578_10203982634825155_5459340140767323841_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-Oiwiuat8P_A/U2YFA5PFp-I/AAAAAAAADzU/zvaAqVdcGCU/s1600/1499578_10203982634825155_5459340140767323841_n.jpg" height="180" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-WVRThjg8Jdc/U2YFFUuzdnI/AAAAAAAADzc/OUQhqkyDKPY/s1600/10314481_10203982634345143_1232761334920741994_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-WVRThjg8Jdc/U2YFFUuzdnI/AAAAAAAADzc/OUQhqkyDKPY/s1600/10314481_10203982634345143_1232761334920741994_n.jpg" height="180" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-4425148423292144392014-04-22T08:55:00.002-03:002014-04-22T08:55:53.919-03:00module-assistant on Debian with a custom KernelIf you get this error:
<br />
<br />
<blockquote class="tr_bq">
# m-a -v -k"/usr/src/linux-headers-$(uname -r)/" a-i openafs<br />Updated infos about 1 packages<br />Bad kernel version specification at /usr/bin/m-a line 568, <$apt> line 9.</blockquote>
<div>
<br /></div>
<div>
You should also use the -l (ell) option:</div>
<div>
<br /></div>
<div>
<blockquote class="tr_bq">
# m-a -vd -k"/usr/src/linux-headers-$(uname -r)/" -l $(uname -r) a-i openafs</blockquote>
</div>
<div>
<br /></div>
<div>
<br /></div>
alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-85314387103227883142014-04-11T17:07:00.000-03:002014-04-11T17:07:58.755-03:00Where the Web was born<iframe src="https://www.flickr.com/photos/alejolp/13784755505/player/" width="500" height="281" frameborder="0" allowfullscreen webkitallowfullscreen mozallowfullscreen oallowfullscreen msallowfullscreen></iframe>alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-14417347062925220242014-03-02T17:56:00.000-03:002014-03-02T17:56:18.050-03:00Jorge Luis Borges<iframe src="http://www.flickr.com/photos/alejolp/12888021663/in/photostream/player/" width="500" height="331" frameborder="0" allowfullscreen webkitallowfullscreen mozallowfullscreen oallowfullscreen msallowfullscreen></iframe>alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-13291079411812002312014-02-26T19:11:00.001-03:002014-02-26T19:11:37.257-03:00OpenSSL Base64 encodingI'll just leave this here in case anyone else is interested:<br />
<br />
<br />
<script src="https://gist.github.com/alejolp/9239685.js"></script>
alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com1tag:blogger.com,1999:blog-9947347.post-21270548131772888212014-01-21T19:14:00.004-03:002014-01-21T19:14:47.154-03:00Programs<blockquote class="tr_bq">
<span style="background-color: #f5f8fa; color: #292f33; font-family: 'Helvetica Neue', Arial, sans-serif; font-size: 14px; line-height: 18px; white-space: pre-wrap;">Programs must be written for people to read, and only incidentally for machines to execute.</span></blockquote>
<a href="http://mitpress.mit.edu/sicp/front/node3.html">Structure and Interpretation of Computer Programs</a>.alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-53972592648854897242014-01-04T03:47:00.004-03:002014-01-10T16:54:13.832-03:00NorCal 49er QRP<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/pFJ-LXDCVQo" width="560"></iframe>
<br />
<br />
Estando de vacaciones y con ganas de hacer un proyecto de radio simple e interesante, me propuse encarar el NorCal 49er QRP. Además, decidí construir mi propia versión del PCB con el <a href="http://www.cadsoftusa.com/">Eagle</a>, y publiqué el diseño y demás información en un <a href="https://github.com/alejolp/49er-qrp">repositorio de GitHub</a>, <a href="https://github.com/alejolp/49er-qrp">https://github.com/alejolp/49er-qrp</a>.alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-82938511061474282312013-08-21T20:22:00.001-03:002013-08-21T20:22:28.160-03:00Ping por Packet AX25Así me está funcionando el ping por AX25, nada mal!<br />
<blockquote class="tr_bq">
# ping -i 15 10.0.0.1<br />PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.<br />64 bytes from 10.0.0.1: icmp_req=1 ttl=64 time=4002 ms<br />64 bytes from 10.0.0.1: icmp_req=2 ttl=64 time=2689 ms<br />64 bytes from 10.0.0.1: icmp_req=4 ttl=64 time=2851 ms<br />64 bytes from 10.0.0.1: icmp_req=5 ttl=64 time=3382 ms<br />64 bytes from 10.0.0.1: icmp_req=7 ttl=64 time=3258 ms<br />64 bytes from 10.0.0.1: icmp_req=9 ttl=64 time=2753 ms<br />64 bytes from 10.0.0.1: icmp_req=12 ttl=64 time=4070 ms<br />64 bytes from 10.0.0.1: icmp_req=13 ttl=64 time=3859 ms<br />64 bytes from 10.0.0.1: icmp_req=15 ttl=64 time=4178 ms<br />64 bytes from 10.0.0.1: icmp_req=17 ttl=64 time=4264 ms<br />64 bytes from 10.0.0.1: icmp_req=18 ttl=64 time=3541 ms<br />64 bytes from 10.0.0.1: icmp_req=20 ttl=64 time=4856 ms<br />64 bytes from 10.0.0.1: icmp_req=22 ttl=64 time=4018 ms<br />64 bytes from 10.0.0.1: icmp_req=23 ttl=64 time=5313 ms<br />64 bytes from 10.0.0.1: icmp_req=25 ttl=64 time=3723 ms<br />64 bytes from 10.0.0.1: icmp_req=27 ttl=64 time=2809 ms<br />64 bytes from 10.0.0.1: icmp_req=28 ttl=64 time=4391 ms<br />64 bytes from 10.0.0.1: icmp_req=29 ttl=64 time=6268 ms<br />64 bytes from 10.0.0.1: icmp_req=30 ttl=64 time=6058 ms<br />64 bytes from 10.0.0.1: icmp_req=31 ttl=64 time=4279 ms<br />64 bytes from 10.0.0.1: icmp_req=32 ttl=64 time=5625 ms<br />64 bytes from 10.0.0.1: icmp_req=33 ttl=64 time=3763 ms<br />64 bytes from 10.0.0.1: icmp_req=34 ttl=64 time=2911 ms<br />64 bytes from 10.0.0.1: icmp_req=35 ttl=64 time=2853 ms<br />64 bytes from 10.0.0.1: icmp_req=36 ttl=64 time=2718 ms<br />64 bytes from 10.0.0.1: icmp_req=37 ttl=64 time=2789 ms<br />64 bytes from 10.0.0.1: icmp_req=38 ttl=64 time=2944 ms<br />64 bytes from 10.0.0.1: icmp_req=39 ttl=64 time=3699 ms<br />64 bytes from 10.0.0.1: icmp_req=41 ttl=64 time=3798 ms<br />64 bytes from 10.0.0.1: icmp_req=44 ttl=64 time=2918 ms<br />^C<br />--- 10.0.0.1 ping statistics ---<br />44 packets transmitted, 30 received, 31% packet loss, time 645337ms<br />rtt min/avg/max/mdev = 2689.509/3819.856/6268.794/986.186 ms</blockquote>
<div>
<br /></div>
alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-68041741514207930142013-08-16T23:51:00.000-03:002013-08-21T15:17:15.616-03:00Medidor de ROE digital con Arduino<a href="http://www.flickr.com/photos/alejolp/9528343362/" title="Arduino SWR Meter by alejolp, on Flickr"><img alt="Arduino SWR Meter" height="333" src="http://farm3.staticflickr.com/2888/9528343362_cd669cb2db.jpg" width="500" /></a><br />
<br />
Tal como adelanté en <a href="http://alejolp.blogspot.com.ar/2013/08/la-historia-del-puente-de-roe-xq2fod.html">mi anterior entrada</a>, una mejora al <a href="http://ludens.cl/Electron/swr/swr.html">puente de ROE de XQ2FOD</a> que le hice fue la de reemplazar los medidores analógicos por un display LCD controlado con un Arduino (ATmega328p).<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/9525554181/" title="Arduino SWR Meter by alejolp, on Flickr"><img alt="Arduino SWR Meter" height="333" src="http://farm3.staticflickr.com/2842/9525554181_e859f452ff.jpg" width="500" /></a>
<br />
<br />
El circuito es demasiado simple como para dibujarlo, la idea es usar la librería <a href="http://arduino.cc/es/Tutorial/LiquidCrystal">LiquidCristal de Arduino</a> y reemplazar en el circuito de XQ2FOD la entrada a los medidores analógicos por las entradas Analog0 y Analog1 en el Arduino. Se pueden ver más fotos en <a href="http://www.flickr.com/photos/alejolp/sets/72157629000257387/">mi galería de Flickr</a>.<br />
<br />
El código fuente del programa cargado en el Arduino <a href="https://gist.github.com/alejolp/6254971">se puede encontrar acá</a>. En programa se encarga de leer constantemente las entradas 0 y 1 analógicas, y hacer los cálculos de SWR (sacados del capítulo de Lineas de Transmisión del ARRL Handbook 2010).<br />
<br />
<div style="text-align: center;">
<span style="font-family: Courier New, Courier, monospace;">p = sqrt(Pr/Pf);</span></div>
<div style="text-align: center;">
<span style="font-family: Courier New, Courier, monospace;">SWR = (1+p) / (1-p);</span></div>
<br />
Además como se puede ver en el codigo fuente, se calcula el promedio de los datos leídos para evitar que el display LCD parpadee cuando los datos de entrada fluctúen en el tiempo.<br />
<br />
LU4EXT<br />
<br />
<br />
<br />alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com4tag:blogger.com,1999:blog-9947347.post-45328029026646858662013-08-13T12:46:00.002-03:002013-08-21T15:17:34.212-03:00Arduino Due ARM<a href="http://www.flickr.com/photos/alejolp/9503850116/" title="Arduino Due ARM by alejolp, on Flickr"><img alt="Arduino Due ARM" height="333" src="http://farm4.staticflickr.com/3779/9503850116_fe98a13288.jpg" width="500" /></a><br />
<br />
El nuevo integrante de la <a href="http://www.flickr.com/photos/alejolp/sets/72157632357997359/">familia de Arduinos</a>.alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-62697666333448079492013-08-13T12:39:00.001-03:002013-08-17T00:13:44.078-03:00La historia del puente de ROE XQ2FOD<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-B7qOdne3P7w/UgcRzz8O0LI/AAAAAAAACcU/YqjFQ1LiSik/s1600/Swr-xq2fod.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://2.bp.blogspot.com/-B7qOdne3P7w/UgcRzz8O0LI/AAAAAAAACcU/YqjFQ1LiSik/s320/Swr-xq2fod.gif" width="286" /></a></div>
<br />
Hace algunos años buscando cómo armar mi propio medidor de ROE me encontré este <a href="http://ludens.cl/Electron/swr/swr.html">excelente circuito de XQ2FOD</a> (<a href="http://ludens.cl/Electron/swr/swr.html">link acá</a>), donde el autor asegura que funciona en todas las bandas populares de Radio Aficionados, desde 80 metros hasta 1.3 Ghz. Sucede que para que funcione en frecuencias altas (y no tan altas también) debe estar bien construido, ya que cualquier error mecánico afecta la lectura del instrumento.<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/6750154441/" title="DSC01047b by alejolp, on Flickr"><img alt="DSC01047b" height="375" src="http://farm8.staticflickr.com/7167/6750154441_34872d857e.jpg" width="500" /></a><br />
<br />
Este fue la primer versión que armé, hace casi 20 meses, ignorando toda advertencia de XQ2FOD en el artículo inicial. El primer comentario que tuve fue que debía armarlo con los alambres lo más cortitos que se puedan, hasta el punto de que se le podían limar la pintura a las resistencias para no tener los alambres. En efecto, este medidor no servía y marcaba cualquier cosa en el instrumento.<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/6993955719/" title="Carga Fantasma 50 Ohm by alejolp, on Flickr"><img alt="Carga Fantasma 50 Ohm" height="375" src="http://farm8.staticflickr.com/7046/6993955719_d3f90fb652.jpg" width="500" /></a><br />
<br />
Luego de armar una versión un poco más compacta (no mucho más), decidí que necesitaba una carga fantasma para poder medir el propio instrumento y ver si efectivamente marcaba 1:1 de ROE con 50 Ohm de carga. La anterior foto fue uno de los intentos de carga, donde la aguja se disparaba marcando bastante ROE. En efecto, la carga estaba muy mal hecha.<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/7011522969/" title="Carga Fantasma 50 Ohm - N by alejolp, on Flickr"><img alt="Carga Fantasma 50 Ohm - N" height="375" src="http://farm8.staticflickr.com/7083/7011522969_08f88181d3.jpg" width="500" /></a><br />
<br />
Luego de varios intentos, terminé con una carga como la que se puede ver en la foto. Ya con esta carga, la actual versión del puente de ROE hacía que el instrumento marque 1.0 de ROE, ¡todo un avance!
Hace algunos meses encontré el blog de LU1AR donde describe una <a href="http://lu1ar.blogspot.com.ar/2012/11/la-carga-fantasma-para-uhf-de-lu1ar.html">carga fantasma de baja potencia</a>, de muy fácil construcción, que bien armada puede llegar hasta 1.3 Ghz sin problemas (<a href="http://lu1ar.blogspot.com.ar/2012/11/la-carga-fantasma-para-uhf-de-lu1ar.html">ver acá</a>). Tengo pendiente armar una de estas ya que no tengo una buena carga fantasma.<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/7015523285/" title="Puente de ROE XQ2FOD versión 2 by alejolp, on Flickr"><img alt="Puente de ROE XQ2FOD versión 2" height="375" src="http://farm7.staticflickr.com/6216/7015523285_4949ec8cb5.jpg" width="500" /></a><br />
<br />
Siguiendo con la idea de mantener las distancias de los alambres lo más cortas posible, terminé con un puente como en la imagen anterior. En este caso, el puente marcaba menos de 1.1 de ROE con mi carga artesanal en VHF.<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/7015523291/" title="Puente de ROE XQ2FOD versión 2 by alejolp, on Flickr"><img alt="Puente de ROE XQ2FOD versión 2" height="375" src="http://farm7.staticflickr.com/6233/7015523291_d6219b00cd.jpg" width="500" /></a><br />
<br />
Además, la siguiente mejora fue, por un lado, reemplazar los diodos 1N34 originales por diodos 1N5711 (azules en la foto), cortesía de un colega Radio Aficionado. En teoría, estos dioditos deberían funcionar bien y sin problemas hasta UHF.<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/7032653137/" title="Arduino SWR Meter by alejolp, on Flickr"><img alt="Arduino SWR Meter" height="375" src="http://farm8.staticflickr.com/7040/7032653137_1d59df8ae3.jpg" width="500" /></a><br />
<br />
Por el otro, otra mejora que le hice al circuito fue reemplazar los medidores de aguja analógicos originales por un microcontrolador (Arduino Atmega328), mostrando el valor del ROE (SWR en inglés) en un display de LCD. Pueden ver <a href="http://alejolp.blogspot.com.ar/2013/08/medidor-de-roe-digital-con-arduino.html">detalles de este proyecto acá</a>.<br />
<br />
Esta última fue la versión que tuve armada durante casi un año, hasta que hace unos días decidí armar una mejor, que pueda llegar hasta microondas.<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/9438033241/" title="Puente de ROE XQ2FOD versión 3 by alejolp, on Flickr"><img alt="Puente de ROE XQ2FOD versión 3" height="333" src="http://farm6.staticflickr.com/5452/9438033241_29ebfbe160.jpg" width="500" /></a><br />
<br />
Tal como comenta XQ2FOD en su artículo, utilizando componentes SMT se puede lograr un puente de ROE que permita medir hasta muy altas frecuencias. Es por esto que decidí armarlo de esta manera, llegando al primer prototipo que se puede ver en la imagen anterior.
Usé los mismos diodos de siempre, y las resistencias son seis de 100 Ohm SMT apareadas en paralelo, obtenidas de un viejo circuito de impresora rota. La placa es Epoxy de 1.5mm, y del otro lado (donde no se ven en la foto) es puro cobre de plano a tierra, conectado también al chasis de los conectores.<br />
<br />
En la foto se puede ver una linea de transmisión de casi 4 cm, esto fue la primer prueba, me sobró bastante circuito ya que los componentes son pocos, y decidí dejarla ya que me pareció que no iba a molestar.
En la práctica esto no es cierto, el circuito debe ser del menor tamaño posible, y a menos que esté muy bien construido recién ahí la línea no debería molestar. Este no fue mi caso, no está bien construido, por lo que el siguiente paso fue reducir el tamaño del circuito.
Midiéndolo con un analizador de antenas MFJ prestado de otro colega, el anterior puente marcaba 1.5 de ROE en VHF, un valor bastante alto para lo que debería ser el puente. Es por esto que decidí construirlo nuevamente utilizando la porción del circuito libre.<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/9474601171/" title="Puente de ROE XQ2FOD versión 4 by alejolp, on Flickr"><img alt="Puente de ROE XQ2FOD versión 4" height="333" src="http://farm8.staticflickr.com/7440/9474601171_965d17991a.jpg" width="500" /></a><br />
<br />
En esta nueva versión usé resistencias nuevas (sin reciclar de otro aparato), donde además las resistencias son de mayor tamaño mecánico, permitiendo disipar más calor. Además, en vez de soldarle una carga fantasma de dudoso valor (en la foto anterior se pueden ver dos resistencias normales de 100 Ohm en paralelo en la punta), decidí usar una carga de 50 Ohm profesional.
Esta carga de 50 Ohm que me prestaron fue medida profesionalmente y que mostró llegar con un ROE (casi) plano hasta 3 Ghz. Con la carga fantasma profesional, y el medidor de antenas MFJ de siempre, pude ver que mi puente de ROE tiene 1.1 de ROE en VHF.
Un dato importante es que al medir el ROE de la carga directamente, el MFJ también marcaba 1.1 de ROE en VHF, por lo que es muy posible y probable que cualquier error que marque el MFJ en mi puente pueda también deberse a la falta de precisión del MFJ en altas frecuencias. Para estar seguro debo conseguir un segundo medidor que me permita medir en UHF, ya que esta versión del medidor MFJ solo llega hasta VHF. Además, le tengo infinita más confianza a la carga de 50 Ohm profesional que al MFJ.<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/9484524372/" title="Puente de ROE XQ2FOD versión 4.1 by alejolp, on Flickr"><img alt="Puente de ROE XQ2FOD versión 4.1" height="333" src="http://farm8.staticflickr.com/7330/9484524372_c82d1c6af3.jpg" width="500" /></a><br />
<br />
Arriba se puede ver la última versión del puente, donde el único cambio es el recorte del PCB al mínimo tamaño posible.<br />
<br />
<a href="http://www.flickr.com/photos/alejolp/9477387410/" title="Puente de ROE XQ2FOD versión 4 by alejolp, on Flickr"><img alt="Puente de ROE XQ2FOD versión 4" height="333" src="http://farm4.staticflickr.com/3715/9477387410_f18e5defdb.jpg" width="500" /></a><br />
<br />
Un experimento que decidí hacer fue conectar un acoplador direccional al puente de ROE. En teoría, el acoplador debería generar por la línea acoplada una señal en caso de que haya ROE en lo que esté conectado (el puente en este caso). Mediante mi osciloscopio decidí medir qué llegaba desde esta línea acoplada, y hasta donde pude ver, la pantalla del osciloscopio no se movía, dando a entender que el puente debería estar bien construido.
Con el acoplador también se puede construir un medidor de ROE en una antena, sin embargo esto queda para otro momento, ya que a mi me interesaba tener el puente de XQ2FOD funcionando.
Si quieren ver la historia completa de construccion del puente de ROE de XQ2FOD, se puede ver <a href="http://www.flickr.com/photos/alejolp/sets/72157629000257387/">la colección de fotos en mi cuenta de Flickr, acá</a>.<br />
<br />
73 LU4EXT, Alejandro.alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com2tag:blogger.com,1999:blog-9947347.post-59140624811534905602013-08-01T23:44:00.004-03:002013-08-17T00:14:32.035-03:00Audio Amp con TDA2005<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.flickr.com/photos/alejolp/9406725036/" style="margin-left: 1em; margin-right: 1em;" title="TDA2005 Audio Amp by alejolp, on Flickr"><img alt="TDA2005 Audio Amp" height="333" src="http://farm3.staticflickr.com/2831/9406725036_d9ea0dc48b.jpg" width="500" /></a></div>
<br />
<br />
Construido tal cual muestra el primer ejemplo de aplicación del datasheet TDA2005. Suena buenísimo.alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-57174562526360871212013-07-28T20:13:00.003-03:002013-07-28T20:13:38.104-03:003er Torneo Argentino de Programación<span style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 13px;">(favor de difundir a posibles interesados)</span><br />
<div class="gmail_quote" style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: 13px;">
<div dir="ltr">
<div>
<br /><b>3er TORNEO ARGENTINO DE PROGRAMACIÓN</b></div>
<div>
5 de octubre de 2013</div>
<div>
<br /></div>
<div>
<b>Sedes</b>: Bahía Blanca (UNS), Buenos Aires (UBA), Córdoba (UNC), La Plata (UNLP), Neuquén (UNComa), Río Cuarto (UNRC), Río Turbio (UNPA) y Santa Fe (UNL)</div>
<div>
<br /></div>
<div>
El 5 de octubre se llevará a cabo la tercera edición del Torneo Argentino de Programación, en el que compiten equipos compuestos por 3 estudiantes de instituciones de educación superior de Argentina. Cada institución puede tener varios equipos que la representen, y cada equipo puede competir en la sede que le resulte más conveniente.</div>
<div>
<br /></div>
<div>
El torneo consiste en resolver un conjunto de problemas algorítmicos en un plazo de 5 horas. La solución a cada problema es un programa que se envía mediante un sistema especial al jurado. El jurado corrige en el momento mediante casos de prueba secretos (test de caja negra) y el equipo se entera al instante si la solución enviada es correcta, de manera que puede corregirla y reenviarla tantas veces como sea necesario.</div>
<div>
<br /></div>
<div>
Este torneo se enmarca dentro de la competencia ACM-ICPC (The ACM International Collegiate Programming Contest, auspiciada por IBM a nivel internacional, ver <a href="http://icpc.baylor.edu/" style="color: #1155cc;" target="_blank">http://icpc.baylor.edu/</a>). Se entregarán certificados oficiales de la ACM-ICPC, tanto de participación como de posición obtenida.</div>
<div>
<br /></div>
<div>
Las instituciones que así lo deseen (no es obligatorio) pueden usar el torneo para seleccionar sus equipos para la Competencia Regional Latinoamericana 2013. A partir de la competencia regional quedan seleccionados los equipos latinoamericanos que participarán en la final mundial en Ekaterinburgo, Rusia, en 2014. La sede Argentina de la regional contará este año con el apoyo de la Fundación Sadosky .</div>
<div>
<br /></div>
<div>
<b>QUIÉNES PUEDEN PARTICIPAR</b></div>
<div>
<br /></div>
<div>
Las condiciones que deben cumplir los alumnos que quieran participar son las mismas de la Competencia Regional Latinoamericana.</div>
<div>
<br /></div>
<div>
Pueden encontrar información sobre las reglas, problemas de ediciones anteriores de la Competencia Regional y del Torneo Argentino, así como otros links de interés en la siguiente página:</div>
<div>
<br /></div>
<div>
<a href="http://www.dc.uba.ar/icpc/" style="color: #1155cc;" target="_blank">http://www.dc.uba.ar/icpc/</a></div>
<div>
<br /></div>
<div>
<b>INSCRIPCIÓN:</b></div>
<div>
<br /></div>
<div>
Los datos para la inscripión se enviarán más cerca de la fecha de la competencia.</div>
<div>
<br /></div>
<div>
<b>ORGANIZACIÓN GENERAL:</b></div>
<div>
<ul>
<li>Pablo Ariel Heiber (pheiber.at.dc.uba.ar)</li>
</ul>
</div>
<div>
<b>ORGANIZADORES LOCALES:</b></div>
<div>
<ul>
<li>Bahía Blanca: Nicolás Álvarez, UNS (naa.at.cs.uns.edu.ar)</li>
<li>Buenos Aires: Pablo Ariel Heiber, FCEyN, UBA (pheiber.at.dc.uba.ar)</li>
<li>Córdoba: Eric Destefanis, FaMAF, UNC (edestefanis.at.gmail.com)</li>
<li>La Plata: Alejandro Santos, FInfo, UNLP (alejolp.at.gmail.com)</li>
<li>Neuquén: Lidia López, FaI, UNComa (lidia.lopez.at.fi.uncoma.edu.ar)</li>
<li>Río Cuarto: Francisco Bavera, FCEFQyN, UNRC (pancho.at.dc.exa.unrc.edu.ar)</li>
<li>Río Turbio: Diana Cruz, UART, UNPA (dianalrcruz.at.gmail.com)</li>
<li>Santa Fe: Emmanuel Rojas Fredini, FICH, UNL (erojasfredini.at.gmail.com)</li>
</ul>
</div>
<div>
<br /></div>
</div>
</div>
alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0tag:blogger.com,1999:blog-9947347.post-82500752603251928482013-07-08T00:13:00.001-03:002013-07-08T17:56:52.649-03:00Distorsión Casera para Guitarra Eléctrica<iframe width="420" height="315" src="//www.youtube.com/embed/2XVq-Kf8tKE" frameborder="0" allowfullscreen></iframe>
<br />
<br />
Algunas fotos del <a href="http://www.flickr.com/photos/alejolp/sets/72157634316742826/">circuito en Flickr</a>.alejolphttp://www.blogger.com/profile/14949586999780473522noreply@blogger.com0