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.

Archivos en MEDIA Django 1.11+ privados (requerir autenticación)

A menudo querremos ofrecer archivos privados en nuestra aplicación Django. La solución más sencilla a esta función es hacer una redirección vía regex a una función que lleve el decorador require_login, de la librería de Django.

Dicha redirección deberá ser incluida en el archivo urls.py principal de nuestro proyecto. Un ejemplo de implementación de esta funcionalidad es el siguiente:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

@login_required
def protected_serve(request, path, document_root=None, show_indexes=False):
    print("Serving " + path)
    return serve(request, path, document_root, show_indexes)

urlpatterns += [
    url( r'^%s(?P<path>.*)$'% settings.MEDIA_URL[1:], protected_serve, {'document_root': settings.MEDIA_ROOT}),
]

Modificando la ruta podrás distinguir qué archivos quedan privados y cuáles no. Si tengo tiempo escribiré un par de ejemplos. Gracias por leerme 😉

Fuente: http://blog.majsky.cz/django-protected-media-files/

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.

Obtener coordenadas en un plano al hacer clic sobre él | Unity 5.6+

El siguiente snippet pretende ilustrar cómo se pueden obtener las coordenadas del mundo real al realizar un clic sobre la pantalla. Es válido para, al menos, las versiones de Unity 5.6 y superiores y está escrito en C#.

Cuando el usuario realiza una pulsación sobre la pantalla es, a priori, imposible determinar las coordenadas espaciales del punto donde pretendía pulsar, ya que para lograr esto se necesita una referencia. Es como si señaláramos a un cielo estrellado y dijéramos… ¡quiero las coordenadas de ese punto! Bien, ¿pero con respecto a qué?

En primer lugar debemos crear una referencia; en concreto un plano geométrico que nos servirá como base de operaciones. No confundas este plano con la forma geométrica primitiva de Unity que comparte su mismo nombre; este plano es una representación matemática de un plano en el espacio tridimensional. Puedes leer más acerca de los planos en Unity haciendo clic aquí, y sobre los planos geométricos aquí.

Una vez creado nuestro plano, plane, en la función update pedimos que cada vez que el usuario haga clic con el botón izquierdo del ratón, se cree un rayo (o semirrecta) geométrico que comience en el punto de la pantalla donde se ha realizado la pulsación. A continuación creamos una variable, rayDistance, que pasamos por referencia a la función plane.Raycast, la cuál creará la intersección entre nuestro rayo y el plano geométrico anteriormente creado. rayDistance será el resultado del cálculo de la longitud de la semirecta cuyo origen sea la posición del objeto que invoca a la función y el punto de intersección con el plano. Con éste último dato podemos obtener el punto del rayo geométrico situado a la recién calculada distancia. En nuestro caso, como prueba, creamos un cubo en el punto de choque.

Para entender el funcionamiento de este script lo mejor es hacer cuantos experimentos sean necesarios con el código de abajo, y también echarle un vistazo a la siguiente imagen con la que pretendo ilustrar el ejercicio.

  Plane plane = new Plane(Vector3.up, Vector3.zero);
	void Update () {
        if (Input.GetMouseButtonDown(0))
        {
          Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
          float rayDistance;
          if (plane.Raycast(ray, out rayDistance)) // Intersects a ray with the plane.
          {
            pivotPoint = ray.GetPoint(rayDistance);
            GameObject test = GameObject.CreatePrimitive(PrimitiveType.Cube);
            test.transform.position = pivotPoint;
          }
        }
      }

Registro de usuario en Django Rest Framework

Mi solución de registro de usuarios a través de una API rest. No he encontrado ejemplos completos en ninguna parte, y este código bien pudiera no ser óptimo.

#serializers.py
class UserViewSet(viewsets.ModelViewSet):
    """
    A viewset that provides the standard actions
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = (AllowAny, )

    def create(self, request, *args, **kwargs):
        """
        http POST 127.0.0.1:8000/users/ By default asks for permission.
        :param request:
        :return:
        """
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.create(validated_data=request.data)
            #serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#views.py
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        """
        Returns all the Avatars id related to one user. Must set the related_name from the many part.
        """
        avatars = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
        model = User
        fields = ('id', 'email', 'avatars', 'account_type', 'password', 'username')

    def create(self, validated_data):
        """
        We've to override the create serializer method in order to call to our custom create_user
        http://www.django-rest-framework.org/api-guide/serializers/#saving-instances
        :param validated_data: Incoming POST data
        :return: A created user instance
        """
        account_type = AccountType.objects.get(pk=validated_data['account_type'])
        email = validated_data['email']
        password = validated_data['password']
        username = validated_data['email']
        return User.objects.create_user(username=username, account_type=account_type, email=email, password=password) # Alternative: User.objects.create(**validated_data)

Contraseñas almacenadas en texto plano en Django Admin

Al configurar la interfaz de administración de nuestro usuario, sea personalizado o no, debemos heredar de la clase.

UserAdmin

Si simplemente implementamos la administración con una linea como la siguiente:

admin.site.register(User, CustomUserAdmin)

Al editar un nuevo usuario el sistema de cifrado de Django no procesará la petición y, por lo tanto, la contraseña quedará almacenada en texto plano en nuestra base de datos. Contraseña que, además, no servirá para autenticar al usuario ya que Django tratará de decodificar la contraseña que ya de por sí está decodificada en la base de datos para compararla con la introducida por el usuario.

Por suerte la solución es bien sencilla. Simplemente deja tu admins.py así:

from django.contrib.auth.admin import UserAdmin
class CustomUserAdmin(UserAdmin):
    pass

admin.site.register(User, CustomUserAdmin)

O si no quieres personalizar las opciones de tu usuario, así:

from django.contrib.auth.admin import UserAdmin

admin.site.register(User, UserAdmin)

Fecha de creación y edición automáticas en Django

En Django la fecha de creación y modificación no se añade por defecto a nuestros modelos, como sí ocurre en otros frameworks como Ruby On Rails. La forma más elegante de añadir esta funcionalidad a tus modelos es crear una clase base que herede de models.Model y luego hacer que todos tus modelos hereden de la misma.

class BaseModel(models.Model):
    created_date = models.DateTimeField(_('Date created'), auto_now_add=True)
    modified_date = models.DateTimeField(_('Date modified'), auto_now=True)

    class Meta:
        abstract = True

El resto de nuestros modelos donde queramos tener las fechas de creación y actualización automáticas deberán ser del tipo:

class AccountType(BaseModel):
    name = models.CharField(_('Name of this account type ie: Free'), blank=False, max_length=254)
    description = models.TextField(_('Explain the user what he can and can not do with this account'), blank=True, max_length=512)

UserViewSet Django User – Ejemplo completo

http GET 127.0.0.1:8000/users/ ‘Authorization: Token e9e95a81da6f5c3e37ed63ef3c2eb75d0ae1a694’

# serializers.py
class UserSerializer(serializers.ModelSerializer):

    """ Returns all the Avatars id related to one user. Must set the related_name from the many part. """
    avatars = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    class Meta:
        model = User
        fields = ('id', 'email', 'avatars', 'account_type', )

    def create(self, validated_data):
        """
        We've to override the create serializer method in order to call to our custom create_user
        http://www.django-rest-framework.org/api-guide/serializers/#saving-instances
        :param validated_data: Incoming POST data
        :return: A created user instance
        """
        user = User.objects.create_user(
            email = validated_data['email'],
            username = validated_data['username'],
            password = validated_data['password'],
        )
        return user

Antes

# urls.py
urlpatterns = [
    url(r'^users/$', views.UserList.as_view()),
    url(r'^user/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
]


# views.py
class UserList(generics.ListAPIView):
    """ Returns a list with all the users data. """
    queryset = User.objects.all()
    serializer_class = UserSerializer


class UserDetail(generics.RetrieveAPIView):
    """ If exists, returns a list with the data of the selected user."""
    queryset = User.objects.all()
    serializer_class = UserSerializer

Deespués

router = DefaultRouter()
router.register(r'users', UserViewSet, 'User')

# Enlazamos con las urls tradicionales
urlpatterns += router.urls
class UserViewSet(viewsets.ViewSet):
    """
    A simple ViewSet for listing or retrieving users.
    """
    # queryset = User.objects.all()
    # @detail_route(methods=['post'], permission_classes=[AllowAny], url_name='list')
    def list(self, request):
        queryset = User.objects.all()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        queryset = User.objects.all()
        user = get_object_or_404(queryset, pk=pk)
        serializer = UserSerializer(user)
        return Response(serializer.data)

Enviar archivos multiform | Django Rest Framework

Creé este snippet para un proyecto en el que necesitaba enviar audio a un servidor vía API REST empleando el formato multipart / form data.

views.py

En el archivo de vistas se encuentra la clase AnswerCreate, que no se encarga ni más ni menos que de crear respuestas de un examen y redirigirlas para almacenarlas debidamente en la base de datos. Dicha clase hereda de CreateAPIView, una clase genérica de DRF sobre la cuál puedes leer aquí, aunque resumiento estipula que sólo podrá ser usada para crear (ni actualizar, ni listar, etc). En nuestro queryset tenemos todas las respuestas actualmente almacenadas en la BD, y en la lista de permisos indicamos que sólo usuarios autenticados podrás crear respuestas.

En nuestra lista de parsers encontramos los necesarios para admitir cabeceras que incluyan archivos. Puedes informarte en mayor profundidad sobre los parsers de DRF aquí.

Lo que encontramos a continuación es el método perform_create sobrescrito para adaptarlo a nuestras necesidades. El resto del código, junto con los ejemplos de Postman son bastante legibles.

class AnswerCreate(generics.CreateAPIView): 
    queryset = Answers.objects.all()
    serializer_class = AnswerSerializer
    # Sólo usuarios autenticados
    permission_classes = (permissions.IsAuthenticated,)
    parser_classes = (MultiPartParser,FormParser,)
    
    def perform_create(self, serializer):
        owner = self.request.user

        # audio-answer es la <em>key</em> de la petición http
        if self.request.data.get('audio-answer') is not None:
            audio_answer = self.request.data.get('audio-answer')
            serializer.save(audio_answer = audio_answer)
        else:
            raise Exception("Al audio no pudo ser enviado")

serializers.py

class AnswerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Answers
        fields = ('id', 'student_name',)

models.py

class Answers(models.Model):
    student_name = models.TextField(default="Test student")
    audio_answer = models.FileField(upload_to='uploads')

Dejo adjuntas un par de capturas con una petición de prueba hecha en postman: