Calcular la altura de un árbol general en C++

El siguiente fragmento de código escrito en c++ calcula la altura de un árbol general de forma recursiva empleando plantillas de tipo T. Si bien esta pudiera no ser la forma más eficiente de realizar este procedimiento, es la que mejor escenifica el recorrido de la estructura de un árbol general. Tras el código he añadido un par de explicaciones, que se pueden completar con las dudas que dejes en los comentarios.

template <typename T>
template <typename T>
int Altura(const Agen<T> A, typename Agen<T>::nodo n){
    if( n == Agen<T>::NODO_NULO)
        return -1;
    else{
        // Tomamos al hijo de n
        typename Agen<T>::nodo hijo = A.hijoIzqdo(n);
        int max = -1;
        // Recorremos al mismo y a todos sus hermanos
        while(hijo != Agen<T>::NODO_NULO){
            int aux = Altura(A, hijo);
            if(aux > max)
                max = aux;
            hijo = A.hermDrcho(hijo);
        }
        return max + 1;
    }
}
}

A partir del nodo del árbol A, calculamos la altura, que se define como la longitud de la rama más larga que parte de n. Para aclararnos, la altura de un nodo hoja será 0 (-1 en el algoritmo) y la de la raíz será máxima. Si el nodo que encontramos es nulo, devuelve -1 para ajustar la solución, que de otra forma daría un entero de más. Si no, busca la máxima de las alturas entre el hijo izquierdo del nodo actual y su hermano derecho.

Modificar plantilla de Administración en Django 1.11 + (1.8+)

El siguiente snippet pretende ilustrar de forma directa y sencilla cómo funciona el sistema de plantillas que Django incorpora desde la versión 1.8, aplicado a la sobre-escritura de la plantilla de administración. Para detalles técnicos está la fabula documentación de Django.

Comencemos creando una carpeta de nombre templates, dentro de esta otra llamada admin, y dentro de admin un archivo al que llamaremos base_site.html. La estructura deberá quedar como sigue:

proyecto
*proyecto
*app1
*app2
*appn
*templates
**admin
***base_site.html

A continuación entra en la carpeta de plantillas de administración de Django en Github: https://github.com/django/django/tree/master/django/contrib/admin/templates/admin

Dentro de este directorio busca el archivo base_site.html. Ábrelo, copia el código que haya en su interior y pégalo en el archivo base_site.html que creaste en el paso anterior.

{% extends "admin/base.html" %}

{% block title %}Título de la página{% endblock %}

{% block branding %}


&amp;amp;amp;lt;h1 id="site-name"&amp;amp;amp;gt;&amp;amp;amp;lt;a href="{% url 'admin:index' %}"&amp;amp;amp;gt;Cabecera de la página&amp;amp;amp;lt;/a&amp;amp;amp;gt;&amp;amp;amp;lt;/h1&amp;amp;amp;gt;


{% endblock %}

{% block nav-global %}{% endblock %}

Te quedará algo así, y aquí podrás modificar lo que tú quieras, pero para que los cambios aun se vean reflejados aun nos queda un paso más.

Entra en el archivo settings.py de tu proyecto y encuentra el bloque de código TEMPLATES. Dentro del diccionario DIRS, introduce la siguiente ruta:

os.path.join(BASE_DIR, ‘templates’),

Deberá quedar algo como:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'templates'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },

]

Y ahora sí, al recargar tu página de administración podrás ver que los cambios han surtido efecto. A partir de esto, todo es probar a modificar lo que quieras a partir del proyecto Django original en GitHub.

La mejor forma de crear un entorno de desarrollo WordPress en Linux

Para la renovación de esta misma web tuve que desempolvar mis conocimientos en PHP, así como volver a repensar la forma ideal de instalar un servidor Apache en mi Ubuntu Gnome 14.04 con los mods necesarios para llevar a cabo las modificaciones que tenía en mente. No quería usar máquinas virtuales (docker, vagrant, virtualbox, etc) y XAMPP siempre me acaba dando algún que otro quebradero de cabeza al ejecutarlo en Linux.

Tras pesar y sopesar las infinitas opciones que gurús de todas las razas y religiones sugieren a lo largo ancho y hondo del ciberespacio, decidí acudir a un viejo conocido: Bitnami. Sabía desde hacía tiempo que esta empresa ofrecía una distribución con WordPress embebido, pero no había tenido la oportunidad de probarlo hasta ahora. ¡Y es una maravilla! Ni problema de permisos, bases de datos, versiones de php / apache / phpmyadmin… nada de nada, de la caja a la mesa. Es la opción con mayores parecidos que he encontrado a los virtual environments  de Python.

Te dejo aquí el link para que lo pruebes, y bueno querida lectora o lector, si sabes de alguna otra opción que me dejes en los comentarios, estaré encantado de echarle un ojo. Que pases un buen día 😉

Introducir texto/palabra por teclado vía terminal en Java

En este lenguaje encontramos múltiples formas de introducir texto por teclado mediante una terminal. A continuación expongo las principales mediante un simple código. Recomiendo usar JDK 1.7 o superior y una terminal, ya sea de un sistema Linux o Windows.

*Si decides ejecutar el código desde un IDE como eclipse, la última opción no funcionará ya que, como su nombre indica, está pensada para ser usada desde la terminal.

Si te queda alguna duda tras leerlo todo, siempre te quedarán los comentarios 😉

// En función de los métodos empleados, importar una u otra librería
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.Console;

public class Consola {
    public static void main(String[] args) {
        String texto = null;
        // Librerías: import java.util.BufferedReader; y import java.io.IOException;
        // Nota: Permite introducir espacios y saltos de línea
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Introduce algún texto: ");
        try {
            texto = reader.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Texto introducido: " + texto);

        // Da uso a import java.util.Scanner; A partir de Java 5
        // Nota: Hay que cuidar el buffer IO. De tener varios sc.nextLine() este acabará desbordando.
        Scanner sc = new Scanner(System.in);
        System.out.print("Introduce algún texto: ");
        texto = sc.nextLine();
        System.out.println("Texto introducido: " + texto);

        // Dependencia: import java.io.Console;
        // Nota: Desde Java 6, la opción más recomendada para leer por consola
        Console consola = System.console();
        texto = consola.readLine("Introduce algún texto: ");
        System.out.println("Texto introducido: " + texto);
    }
}

Fuente

[Solución] Error in runnabble ‘Creating Gradle model’

La solución al error:

SDK location not found. Define location with sdk.dir in the local.properties file or with ANDROID_HOME environment variable. See error log for detail.

, es muy simple. Tan sólo sigue los siguientes pasos:

  1. Busca el directorio donde esté instalado tu SDK. Por ejemplo: /home/ernesto/libGDX/sdk-android
  2. Entra en el directorio raíz de tu proyecto Gradle y localiza el archivo local.properties
    1. Si el archivo local.properties no existe, créalo y escribe dentro del mismo la ruta al directorio de tu SDK con el siguiente formato: sdk.dir=/home/ernesto/libGDX/sdk-android Una vez escrito, guarda el archivo y trata de volver a importar el proyecto.
    2. Si el archivo local.propierties sí que existe, edítalo con cualquier editor de textos como gedit o wordpad y añade o sobrescribe la siguiente línea:  sdk.dir=/home/ernesto/libGDX/sdk-android Sustituyendo /home/ernesto/libGDX/sdk-android por el directorio donde se encuentre tu SDK. Guarda el archivo y trata de importar nuevamente tu proyecto Gradle.

Esto es todo, si solucionaste tu problema te animo a que me lo comentes y si no, coméntalo también por aquí abajo y trataré de echarte un cable.

Cifrado César escrito en Java

El cifrado césar consiste en intercambiar las letras de un mensaje un número de posiciones determinadas por una clave. Más información de su historia y funcionamiento haciendo clic aquí.

El código que muestro más abajo es una versión del cifrado César tradicional pero empleando el alfabeto ASCII. Este alfabeto tiene 255 caracteres por lo que las posibilidades de cifrado y la dificultad para desencriptar se ven aumentadas. Sin embargo, las fórmulas que emplearemos son las mismas que se emplearon hace más de 2000 años, con una ligera variación:

*Se usa 27, porque en el alfabeto tradicional tenemos 27 caracteres.

Código ASCII

El código tiene dos versiones, una sin optimizar en la que se desglosa el proceso línea por línea y otra optimizada pero algo menos legible.

Ambos scripts están pensados para ser ejecutados desde una terminal de un sistema operativo en el que se encuentre instalado el JDK 7 u 8 (clic aquí para instalarlo en Linux).

Si tienes algún problema con la entrada de texto en Java haz clic aquí.

Si encuentras bugs, se te ocurren ideas para mejorar el código o lo que sea, te invito a expresarte en los comentarios.

Versión primera

/**
 * Created by erwol on 03/03/2016 at 12:39
 * For further information visit http://erwol.com
 */
import java.util.Scanner;
import java.io.Console;
public class Cesar {
    private static Scanner lee = new Scanner(System.in);
    public static void main(String args[]){
        int op = -1;
        String texto = null;
        Console consola = System.console();
        int clave = 0;
        while(op != 0){
            System.out.print("ntCIFRADO CÉSARn0.- Salirn1.- Cifrarn2.- Descifrarn&gt; ");
            op = lee.nextInt();
            switch(op){
                case 0:break;
                case 1:
                    System.out.printf("1. Introduzca el texto a cifrarn&gt; ");
                    texto = consola.readLine();
                    System.out.printf("2. Introduzca la clave con la que se codificará el texton&gt;");
                    clave = lee.nextInt();
                    System.out.println("3. Cadena cifrada con clave = " + clave + " -&gt;" + cifrar(texto, clave) + "&lt;-");
                break;
                case 2:
                    System.out.printf("1. Introduzca el texto cifradon&gt; ");
                    texto = consola.readLine();
                    System.out.printf("2. Introduzca la clave con la que codificó el texton&gt; ");
                    clave = lee.nextInt();
                    System.out.println("3. Cadena cifrada con clave = " + clave + " -&gt;" + descifrar(texto, clave) + "&lt;-");
                break;
                default:System.out.println("3. Ha introducido una opción no válida. Pruebe de nuevo.");
            }
        }
    }

    static String cifrar(String original, int clave){
        // Inicializado con el tamaño de la cadena original. STRING SON INMUTABLES!
        StringBuilder cifrado = new StringBuilder(original.length());
        int valorASCII = 0;
        for(int i = 0;i &lt; original.length(); i++){
            // 1 Guardamos el valor ASCII (31 - 126) del caracter número i
            valorASCII = (int)(original.charAt(i));

            // 2 Aplicamos la fórmula
            valorASCII = valorASCII + clave % 255;

            // 3 Añadimos el caracter cifrado
            cifrado.append((char)(valorASCII));
        }
        // 4 Devolvemos la conversión de StringBuilder a String
        return cifrado.toString();
    }

    static String descifrar(String original, int clave){
        // Proceso inverso del cifrado
        StringBuilder descifrado = new StringBuilder(original.length());
        int ASCIIcifrado = 0, n = 0;
        for(int i = 0;i &lt; original.length(); i++){
            ASCIIcifrado = (int)(original.charAt(i));
            ASCIIcifrado = ASCIIcifrado - clave % 255;
            descifrado.append((char)(ASCIIcifrado));
        }
        return descifrado.toString();
    }
}

Versión segunda

/**
 * Created by erwol on 04/03/2016 at 13:55
 * For further information visit http://erwol.com
 */
import java.util.Scanner;
import java.io.Console;
public class Cesar_simplificado {
    private static Scanner lee = new Scanner(System.in);

    public static void main(String args[]){
        int op = -1;
        String texto = null;
        Console consola = System.console();
        int clave = 0;
        while(op != 0){
            System.out.print("ntCIFRADO CÉSARn0.- Salirn1.- Cifrarn2.- Descifrarn&gt; ");
            op = lee.nextInt();
            switch(op){
                case 0:break;
                case 1:
                    System.out.printf("1. Introduzca el texto a cifrarn&gt; ");
                    texto = consola.readLine();
                    System.out.printf("2. Introduzca la clave con la que se codificará el texton&gt;");
                    clave = lee.nextInt();
                    System.out.println("3. Cadena cifrada con clave = " + clave + " -&gt;" + cifrar(texto, clave) + "&lt;-");
                    break;
                case 2:
                    System.out.printf("1. Introduzca el texto cifradon&gt; ");
                    texto = consola.readLine();
                    System.out.printf("2. Introduzca la clave con la que codificó el texton&gt; ");
                    clave = lee.nextInt();
                    System.out.println("3. Cadena cifrada con clave = " + clave + " -&gt;" + descifrar(texto, clave) + "&lt;-");
                    break;
                default:System.out.println("Ha introducido una opción no válida. Pruebe de nuevo.");
            }
        }
    }

    static String cifrar(String original, int clave){
        StringBuilder cifrado = new StringBuilder(original.length());
        for(int i = 0;i &lt; original.length(); i++)
            cifrado.append((char)((int)(original.charAt(i)) + clave % 255));
        return cifrado.toString();
    }

    static String descifrar(String original, int clave){
        StringBuilder descifrado = new StringBuilder(original.length());
        for(int i = 0;i &lt; original.length(); i++)
            descifrado.append((char)((int)(original.charAt(i)) - clave % 255));
        return descifrado.toString();
    }
}