Saltar al contenido

Artículos del blog

Sin cola hasta que haga falta: una plataforma de visión con YOLO que creció por evidencia

Por Marco A. Parra, 27 de octubre de 2026 · 4 min de lectura

Una plataforma interna para entrenar e inferir con YOLO empezó con una decisión incómoda: la web esperaba con la conexión abierta mientras la GPU trabajaba, sin cola de tareas. Este artículo cuenta por qué, cómo cada límite se escribió junto con la señal que lo volvería inaceptable, y qué se construyó —y qué no— cuando esas señales llegaron.

architecturecomputer-visiondjangofastapimlopsyolo

Leer más →

Los controles bloquean, no avisan: un agente de IA en mi búsqueda de empleo

Por Marco A. Parra, 27 de octubre de 2026 · 5 min de lectura

Desde agosto, un agente de IA lee ofertas de empleo, las analiza y arma mis CV. Es rápido, y también puede inventar un dato, olvidar una regla o adjuntar el archivo equivocado. Este artículo trata de los controles que lo hacen usable: una aprobación atada al texto exacto, verificaciones que bloquean en vez de avisar, un archivo por cada dato y medir al agente contra mis propias decisiones.

ai-agentsclaude-codehuman-in-the-loopllmpython

Leer más →

La planilla que se convirtió en sistema

Por Marco A. Parra, 21 de agosto de 2026 · 7 min de lectura

Entre 2017 y 2019 una planilla de Excel con macros se convirtió en la especificación de un sistema de control dimensional para aserraderos pyme: pie de metro Bluetooth, app móvil y análisis estadístico en la nube. Este artículo cuenta el método —cuatro puntos de control, nominal frente a objetivo, cartas de desviación— y la decisión de diseño que decide si una herramienta así llega o no a una pyme. Sin código, sin datos de planta.

data-acquisitionoperationsspcwood-industry

Leer más →

Lo que 68 aserraderos nos contaron sobre sus datos

Por Marco A. Parra, 21 de agosto de 2026 · 7 min de lectura

En 2019 fui primer autor del Informe Técnico N.º 223 de INFOR: una encuesta a 68 aserraderos pyme de Maule a Los Lagos sobre sus máquinas y, sobre todo, sobre cómo capturan y usan sus datos. Este artículo recorre lo que encontramos —el 79 % controlaba dimensiones en planillas de papel— y por qué ese diagnóstico terminó convirtiéndose en una especificación de software.

data-acquisitionindustry-4-0operationswood-industry

Leer más →

Tender un puente a un sistema de producción COBOL sin tocarlo

Por Marco A. Parra, 20 de agosto de 2026 · 5 min de lectura

Un sistema de planta en COBOL exportaba cada noche archivos planos fragmentados y nadie podía sacar un informe de ellos. Este artículo recorre la plataforma de integración que convirtió esas exportaciones en un modelo relacional normalizado —ingesta idempotente, fronteras transaccionales y un módulo de planificación encima— y lo que me enseñó sobre modernizar sin reescribir.

backenddjangoetllegacy-systemspostgresql

Leer más →

Metaheurísticas híbridas para la tardanza en job shop: qué funcionó y qué no

Por Marco A. Parra, 20 de agosto de 2026 · 4 min de lectura

Minimizar la tardanza total en un job shop es NP-duro, y las plantas reales añaden restricciones de precedencia que los benchmarks clásicos ignoran. Este artículo explica cómo se combinaron GRASP, VNS e ILS en un motor híbrido, cómo se validaron los resultados estadísticamente y —igual de importante— qué es lo que el estudio no afirma.

metaheuristicsoperations-researchoptimizationpythonscheduling

Leer más →

Ver código


Código de views.py

def index(request):
    return _listing(request, published_posts(), index)


def published_posts():
    return Post.objects.filter(published_at__lte=timezone.now())


def _listing(request, queryset, view, tag=None):
    """Listado paginado: una entrada por artículo en el idioma activo.

    `view` es la vista que llama (index o tag_index): su "Show Code" enseña esa
    vista, la consulta de publicados y este listado, que es donde está el trabajo.
    """
    posts = pick_language(
        queryset.select_related("author").prefetch_related("tags"), translation.get_language()
    )
    page_obj = Paginator(posts, POSTS_PER_PAGE).get_page(request.GET.get("page"))
    logger.debug("Got %d posts (page %s)", len(posts), page_obj.number)
    return render(request, "blog/index.html", {
        "posts": page_obj.object_list, "page_obj": page_obj, "tag": tag,
        **show_code([view, published_posts, _listing], "blog/index.html"),
    })

Plantilla

{% extends "base.html" %}
{% load blog_extras i18n static %}
{% block title %}{% trans "Blog" %} | Marco A. Parra F.{% endblock %}
{% block meta_description %}{% trans "Engineering notes on computer vision, backend architecture and industrial operations, each tied to a real project." %}{% endblock %}
{% block og_title %}{% trans "Blog" %} — Marco A. Parra F.{% endblock %}
{% block og_description %}{% trans "Engineering notes on computer vision, backend architecture and industrial operations, each tied to a real project." %}{% endblock %}
{% block extrahead %}
    {% get_current_language as FEED_LANGUAGE %}
    <link rel="alternate" type="application/atom+xml" href="{% url 'blog_feed' FEED_LANGUAGE %}" title="Atom">
{% endblock %}
{% block content %}
{% get_current_language as CURRENT_LANGUAGE %}
<div class="container blog-list py-4">
    {% if tag %}
        <h1 class="text-center mb-2">{% blocktrans %}Articles tagged “{{ tag }}”{% endblocktrans %}</h1>
        <p class="text-center text-muted mb-4"><a href="{% url 'blog_index' %}">← {% trans "All articles" %}</a></p>
    {% else %}
        <h1 class="text-center mb-4">{% trans "Blog Posts" %}</h1>
    {% endif %}
    {% for post in posts %}
        <article class="blog-entry py-4 border-bottom">
            <div class="d-flex gap-3 align-items-start">
                {% if post.hero_image %}
                    <a href="{% url 'blog-post-detail' post.slug %}" class="flex-shrink-0 d-none d-sm-block" tabindex="-1" aria-hidden="true">
                        <img src="{{ post.hero_image.thumbnail.100x100.url }}" alt="" class="rounded blog-thumb">
                    </a>
                {% elif post.hero_static %}
                    <a href="{% url 'blog-post-detail' post.slug %}" class="flex-shrink-0 d-none d-sm-block" tabindex="-1" aria-hidden="true">
                        <img src="{% static post.hero_static %}" alt="" class="rounded blog-thumb">
                    </a>
                {% endif %}
                <div class="flex-grow-1">
                    <h2 class="h3 mb-1">
                        <a href="{% url 'blog-post-detail' post.slug %}" class="text-reset text-decoration-none">{{ post.title }}</a>
                        {% if post.language != CURRENT_LANGUAGE %}
                            <span class="badge bg-secondary align-middle fs-6"
                                  title="{% trans "This article is only available in this language" %}">{{ post.language|upper }}</span>
                        {% endif %}
                    </h2>
                    <p class="blog-meta text-muted small mb-2">
                        {% include "blog/post-byline.html" %}
                        · {% blocktrans count n=post.content|reading_time %}{{ n }} min read{% plural %}{{ n }} min read{% endblocktrans %}
                    </p>
                    <p class="blog-summary mb-2">{{ post.summary }}</p>
                    {% include "blog/post-tags.html" %}
                    <a href="{% url 'blog-post-detail' post.slug %}" class="btn btn-sm btn-outline-dark">{% trans "Read More" %} →</a>
                </div>
            </div>
        </article>
    {% empty %}
        <p class="text-muted">{% trans "No articles yet." %}</p>
    {% endfor %}
    {% if page_obj.paginator.num_pages > 1 %}
    <nav class="d-flex justify-content-between align-items-center pt-4" aria-label="{% trans "Pagination" %}">
        {% if page_obj.has_previous %}
            <a class="btn btn-sm btn-outline-dark" href="?page={{ page_obj.previous_page_number }}">← {% trans "Newer" %}</a>
        {% else %}<span aria-hidden="true">&nbsp;</span>{% endif %}
        <span class="text-muted small">{% blocktrans with n=page_obj.number m=page_obj.paginator.num_pages %}Page {{ n }} of {{ m }}{% endblocktrans %}</span>
        {% if page_obj.has_next %}
            <a class="btn btn-sm btn-outline-dark" href="?page={{ page_obj.next_page_number }}">{% trans "Older" %} →</a>
        {% else %}<span aria-hidden="true">&nbsp;</span>{% endif %}
    </nav>
    {% endif %}
</div>

{% include 'partials/_show_code.html' %}
{% endblock %}