Emblemas

Energizado por OpenSource
Soporta RSS2
Soporta Atom
Soporta Debian Power User
Energizado por Hacker
Soporta Last.FM
Soporta Ubuntu
Energizado por MySQL

twitter


Un nano cliente de twitter hecho en 30 minutos desde cero en ASP.NET

Un día como cualquier otro, habla por el mensajero de la oficina con mi Sensei y nos pusimos a platicar sobe una entrevista que había hecho a un aspirante a developer donde le pedía que hiciera un programa sencillo consumiendo el API de twitter (Mostrar el Time Line y poder publicar el estatus) y me preguntaba si 1 hora de tiempo era suficiente, hice un "calculo" mental y se me hizo suficiente tiempo para completar la tarea, sin embargo me pregunte si yo podría hacerlo en menos tiempo (solo por pura diversión), puse el cronometro (ya con el IDE abierto y listo) y este fue el resultado después de 30 minutos (momento en el cual consideré que la tarea estaba cumplida).


Paso a Paso



#1 Autentificación

El primer paso fue entonces hacer una autentificación del usuario, para lo cual ASP.NET tiene un control.

#2 Time Line de Twitter

El problema suena complicado pero el API de Twitter es muy amigable y ASP.NET tiene un control que se alimenta con XML, entonces solo tuve que conectar estos dos puntos.

#3 Publicar status

Habría ahorrado mucho tiempo usar LinQ2Twitter pero olvide descargarlo y el tiempo no detenía su marcha así que de la forma más rupestre hice un HttpRequest para hacer update del estatus.

public static bool PostTweet(string username, string password, string tweet)
        {
            try
            {
                // encode the username/password
                string user = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
                // determine what we want to upload as a status
                byte[] bytes = System.Text.Encoding.ASCII.GetBytes("status=" + tweet);
                // connect with the update page
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://twitter.com/statuses/update.xml");
                // set the method to POST
                request.Method = "POST";
                request.ServicePoint.Expect100Continue = false;
                // set the authorisation levels
                request.Headers.Add("Authorization", "Basic " + user);
                request.ContentType = "application/x-www-form-urlencoded";
                // set the length of the content
                request.ContentLength = bytes.Length;
                // set up the stream
                Stream reqStream = request.GetRequestStream();
                // write to the stream
                reqStream.Write(bytes, 0, bytes.Length);
                // close the stream
                reqStream.Close();
            }
            catch (Exception ex) { return false; }
            return true;
        }
 

#4 140 caracteres o menos

Una de las características más conocidas de Twitter es la restricción de los 140 caracteres (o menos), la página de twitter tiene un contador de caracteres que debía incluir en mi programa, así tuve que agregar un par de funciones JavaScript para poder emular esta característica de la página original de twitter

function CountChars()
        {
            document.getElementById("lblCount").value = 140 - document.getElementById("<% = status.ClientID %>").value.length;
        }
 

#5 Talacha

El resto fue solo talacha como decimos coloquialmente, todo el proceso fue muy rápido e indoloro, al presionar F5 probé el programa y todo salio bien (Al menos este programa no iría a las garras de QA).

Ahí está el código...

Si estas interesado en agregarle algo al proyecto, puedes hacerlo en Code Run (el link ya lo puse al principio) y/o mandarme tus comentarios.

Divertimento Programático - Invertir Texto

Cuando era estudiante, alguna vez nos pidieron hacer un programa (Java) que invirtiera el texto que se había escrito en la terminal, este problema que podría resolverlo hasta un mono drogado no despertó ningún interés, sin embargo y para no aburrirme decidí hacer un pequeño cambio de perspectiva. El programa se perdió junto con otras muchas cosas durante los años, pero aquí lo reproduzco (C#/Windows Forms).

El Código

public class StringReflection
    {
        private string InvertedABC = " `˙zʎxʍʌnʇsɹʞdouɯlʞɾıɥƃɟǝpɔqɐ";
        private string StraightABC = "abcdefghijklmnopqrstuvwxyz., ";
        public string Text;
        public StringReflection(string text)
        {
            this.Text = text.ToLower();
        }
        public string Backwards()
        {
            StringBuilder sb = new StringBuilder();
            char[] ɔqɐ = InvertedABC.ToCharArray();
            Array.Reverse(ɔqɐ);
            foreach (char c in Text)
            {
                try
                {
                    sb.Append(ɔqɐ[StraightABC.IndexOf(c)]);
                } catch (Exception) { /*Ignore the missed chars in the subset*/ }
            }
            char [] ʇxǝʇ = sb.ToString().ToCharArray();
            Array.Reverse(ʇxǝʇ);
            return new String(ʇxǝʇ);
        }
    }
 





Si quieren ver el proyecto lo pueden hacer aquí o pueden descargarlo a continuación:

Quitter un cliente ligero y discreto de Twitter

Quitter es un cliente ligero de twitter, además es muy discreto para aquellos entornos en los cuales no te dejan tener el "Twitter" abierto en el navegador. Encontré este cliente de pura casualidad y sin estar buscándolo, cuando lo baje me dio algo de lata configurar lo pero luego de configurado funciona de maravilla.

Lo malo

El programa no te deja escribir acentos o Ñ's peeeeeero tengo un parche de 3 centavos para el código fuente que agrega esta pequeña funcionalidad y claro que si aquí está el parche para que se lo apliquen al código y puedan ser felices y comer perdices.

El parche



El Código Fuente

Este proyecto esta muy bien diseñado y prueba de esto es que copiando el Main del código todo esta claro como el agua:
Sub Main()
        Initialize()
        Dim QuitSelected As Boolean = False
        Do
            WriteLine()
            If _CurrentUser.ScreenName <> String.Empty Then
                WriteLine(String.Format("[{0} ({1})]", _CurrentUser.ScreenName, _HitsRemaining))
            End If
            Write(MAIN_PROMPT)
            Dim Choice As String = ReadKey("acdfhlpqrstu?x")
            Select Case Choice
                Case String.Empty
                    Write("Read ")
                    Read()
                Case "A"
                    WriteLine("About Quitter")
                    About()
                Case "C"
                    WriteLine("Configuration")
                    ConfigureMenu()
                Case "D"
                    Write("Direct messages ")
                    DirectMessageMenu()
                Case "F"
                    WriteLine("Follow user")
                    FollowUser()
                Case "L"
                    WriteLine("Open link")
                    OpenLink()
                Case "P"
                    WriteLine("Post")
                    PostUpdate()
                Case "Q"
                    WriteLine("Quit")
                    If ReadYesNo("Are you sure? (Y/N):") Then
                        QuitSelected = True
                    End If
                Case "R"
                    WriteLine("Reply")
                    Reply()
                Case "S"
                    WriteLine("Search")
                    Search()
                Case "T"
                    WriteLine("Re-tweet")
                    ReTweet()
                Case "U"
                    WriteLine("Unfollow user")
                    UnFollowUser()
                Case "?"
                    WriteLine("Help")
                    ShowHelp()
            End Select
        Loop Until QuitSelected
    End Sub
 

Ordenamiento De Cadenas Por Longitud

Tienes una lista de cadenas y quieres ordenarlas según su longitud, de la más corta a la más larga. Esta misma solución se puede aplicar cambiando el criterio: alfabeticamente, mayor número de vocales, etc. Aquí expongo diferentes implementaciones de la misma estrategia en Java, C#, C++, PowerShell y C# con LinQ.

Introducción

Como buen programador una de las cosas que más odio es hacer algo más de una vez, y lo que odio aún más es tener que explicar lo mismo más de una vez a una o varias personas, así que decidí publicar en mi Blog las respuestas a las preguntas más solicitadas por todos aquellos que me acosan en el correo electrónico, Messenger, celular, etc. (No se hagan ustedes saben quienes son).

El siguiente problema es un clásico, desde estudiantes de primer semestre hasta administradores de sistemas me han preguntado lo mismo (o alguna variante). Inclusive un estudiante me comento que tenia ya un mes intentando resolver este problema (de que los hay, los hay).

Problema

Tenemos una lista de cadenas y queremos ordenarlas de menor longitud a mayor longitud. Veamos pues un ejemplo:

Entrada Salida
Aerocrofobia No
Haba Café
No Haba
Acluofobia Persa
Bienvenido Litros
Amaxofobia Palabra
Palabra Iniciar
Reflexología Platano
Atazagorafobia Gasolina
Persa Autómata
Autómata Amaxofobia
Iniciar Acluofobia
Allodoxafobia Bienvenido
Litros Importante
Apotenmofobia Aracnofobia
Gasolina Reflexología
Platano Aerocrofobia
Café Allodaxofobia
Importante Apotenmofobia
Aracnofobia Atazagorafobia

Solución

A continuación expondré la misma solución en diferentes lenguajes, la solución siempre es la misma, solo se necesita establecer el criterio de ordenamiento en la función o método de ordenamiento.

Versión Java™

Este va primero por que nada arruina más mi día que tener que hablar de este PCENSURADOe lenguaje. Aquí pues el código:

PorLongitud.java

import java.util.Comparator;
class PorLongitud implements Comparator {
        public int compare(Object o1, Object o2)
        {
                String a = (String) o1;
                String b = (String) o2;
                return ( a.length() < b.length() )?-1:1;
        }
        public boolean equals(Object o)
        {
                return this == o;
        }
       
}
 

Programa.java

import java.util.*;
class Programa {
        public static void main(String[] args)
        {
                ArrayList lista = new ArrayList();
                lista.add("Aeroacrofobia");
                lista.add("Haba");
                lista.add("No");
                lista.add("Amaxofobia");
                lista.add("Bienvenido");
                lista.add("Palabra");
                lista.add("Reflexología");
                lista.add("Persa");
                lista.add("Autómata");
                lista.add("Iniciar");
                lista.add("Allodoxafobia");
                lista.add("Litros");
                lista.add("Gasolina");
                lista.add("Platano");
                lista.add("Café");
                lista.add("Importante");
                lista.add("Aracnofobia");
               
                for (Object o : lista) {
                        System.out.println( o );
                }
               
                Collections.sort(lista, new PorLongitud());
               
                for (Object o : lista) {
                        System.out.println( o );
                }
        }
}
 

Versión C# (I love this language)

Saber delegar es la característica más importante de un buen líder programador:

class Program {
        static void Main(string[] args) {
                List<string> lista = new List<string>() {
                        "Aeroacrofobia", "Haba", "No", "Amaxofobia",
                        "Bienvenido", "Palabra", "Reflexología",
                        "Persa", "Autómata", "Iniciar", "Allodoxafobia",
                        "Litros", "Gasolina", "Platano", "Café",
                        "Importante", "Aracnofobia"
                };
                 
                lista.ForEach(delegate(string item){ System.Console.WriteLine(item); });
                lista.Sort(delegate(string a, string b) { return a.Length.CompareTo(b.Length); });
                lista.ForEach(delegate(string item){ System.Console.WriteLine(item); });
        }
}
 

Puedes descargar el código para Visual Studio 2008 aquí:


Para aquellos interesados en LinQ al final de este bloque presento la solución usando solamente LinQ(Para que vean que bonito se programa en C#).

Versión C++

#include <iostream>
#include <list>
#include <string>
#include <algorithm>
using namespace std;
bool PorLogitud(string a, string b)
{
        return ( a.length() < b.length() );
}
int main()
{
        list<string> ListaCadenas;
        list<string>::iterator it;
       
        ListaCadenas.push_back ("Aeroacrofobia");
        ListaCadenas.push_back ("Haba");
        ListaCadenas.push_back ("No");
        ListaCadenas.push_back ("Amaxofobia");
        ListaCadenas.push_back ("Bienvenido");
        ListaCadenas.push_back ("Palabra");
        ListaCadenas.push_back ("Reflexología");
        ListaCadenas.push_back ("Persa");
        ListaCadenas.push_back ("Autómata");
        ListaCadenas.push_back ("Iniciar");
        ListaCadenas.push_back ("Allodoxafobia");
        ListaCadenas.push_back ("Litros");
        ListaCadenas.push_back ("Gasolina");
        ListaCadenas.push_back ("Platano");
        ListaCadenas.push_back ("Café");
        ListaCadenas.push_back ("Importante");
        ListaCadenas.push_back ("Aracnofobia");
        ListaCadenas.sort(PorLogitud);
       
        cout << "Mi Lista:" << endl;
       
        for (it=ListaCadenas.begin(); it!=ListaCadenas.end(); ++it)
                cout << *it << endl;
               
        return 0;
}
 

Versión PowerShell

PS > Get-content -Path cadenas.txt | Sort-Object -Property Length

Versión C# Con LINQ (.NET 3.5)

Haciendo uso de esta nueva característica este problema it’s a fuking peace of cake. Veamos el código:

public static List<string> OrdenarPorLongitud(List<string> lista) {
        var ordenado = from cadena in lista orderby cadena.Length ascending select cadena;
        return ordenado.ToList();
}
 

¿La quieren aún más fácil?, pues ahí les va con expresiones Lamda:

class Program {
        static void Main(string[] args) {
       
                List<string> lista = new List<string>() {
                "Aeroacrofobia", "Haba", "No", "Amaxofobia",
                "Bienvenido", "Palabra", "Reflexología",
                "Persa", "Autómata", "Iniciar", "Allodoxafobia",
                "Litros", "Gasolina", "Platano", "Café",
                "Importante", "Aracnofobia" };
               
                lista.ForEach(delegate(string item){ System.Console.WriteLine(item); });
                lista.Sort( (a,b) => a.Length.CompareTo(b.Length) );
                lista.ForEach(delegate(string item){ System.Console.WriteLine(item); });
        }
}
 

Conclusión

No hay razón para reinventar la rueda, el programador más listo es aquel que se duerme más temprano.

music@last.fm