<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Kervin's Tech Blog]]></title><description><![CDATA[Desarrollador web con pasión por crear soluciones, experimentar y aprender cosas nuevas. Fan de las buenas películas y documentales.]]></description><link>https://kervin.blog</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1627176653234/5L_i6FgdJ.png</url><title>Kervin&apos;s Tech Blog</title><link>https://kervin.blog</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 20:34:48 GMT</lastBuildDate><atom:link href="https://kervin.blog/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[De PSeInt al navegador: construyendo Codoritmo en público]]></title><description><![CDATA[Hay herramientas que te marcan. Para muchos en Latinoamérica, PSeInt fue una de ellas. Fue donde aprender lógica dejó de sentirse complicado y empezó a tener sentido.
Codoritmo nace de ahí, no como re]]></description><link>https://kervin.blog/de-pseint-al-navegador-construyendo-codoritmo-en-p-blico</link><guid isPermaLink="true">https://kervin.blog/de-pseint-al-navegador-construyendo-codoritmo-en-p-blico</guid><category><![CDATA[pseudocode]]></category><category><![CDATA[Programación]]></category><category><![CDATA[software development]]></category><category><![CDATA[logical operator]]></category><category><![CDATA[algoritmos-e-estrutura-de-dados]]></category><category><![CDATA[Desarrollo Web]]></category><category><![CDATA[inteligencia artificial ]]></category><category><![CDATA[ingeniería de software]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Wed, 01 Apr 2026 07:13:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/609de22fb684eb4cd52c546e/0d51f739-c0e1-426c-8754-7fbb5a8480fc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hay herramientas que te marcan. Para muchos en Latinoamérica, PSeInt fue una de ellas. Fue donde aprender lógica dejó de sentirse complicado y empezó a tener sentido.</p>
<p>Codoritmo nace de ahí, no como reemplazo, sino como una forma de llevar esa misma idea a un entorno distinto.</p>
<p>PSeInt, creado por Pablo Novara, ha sido durante años una de las herramientas más utilizadas para enseñar programación básica en español. Si nunca lo has usado, puedes ver el proyecto aquí: <a href="https://pseint.sourceforge.net">PSeInt (sitio oficial)</a>.</p>
<p>Recuerdo que en mis primeros años en la universidad, ya hace más de una década, se convirtió en una forma de plasmar mis pensamientos. Me ayudaba a ordenar ideas y a traducir lógica en algo tangible, sin tener que preocuparme todavía por un lenguaje específico. Y eso es algo que se queda contigo.</p>
<p>A partir de ahí nace Codoritmo. Puedes ver el proyecto aquí: <a href="https://www.codoritmo.com/">Codoritmo</a>.</p>
<h3>Qué hace Codoritmo (por ahora)</h3>
<ul>
<li><p>Escribes pseudocódigo directamente en el navegador</p>
</li>
<li><p>Generas diagramas de flujo automáticamente</p>
</li>
<li><p>Exportas tu lógica a JavaScript (por ahora, con idea de expandirlo)</p>
</li>
<li><p>Mantiene compatibilidad con el dialecto de PSeInt</p>
</li>
</ul>
<p>Todo sin instalación y sin cambiar de contexto.</p>
<img src="https://cdn.hashnode.com/uploads/covers/609de22fb684eb4cd52c546e/d238b08f-1bd3-415b-a2bb-02251bdbe986.png" alt="" style="display:block;margin:0 auto" />

<img src="https://cdn.hashnode.com/uploads/covers/609de22fb684eb4cd52c546e/02787c8a-391a-409d-b254-a08a4618d03d.png" alt="" style="display:block;margin:0 auto" />

<p>Pero más allá de las funcionalidades, la idea es simple: tener un entorno donde la lógica se pueda entender, visualizar y eventualmente llevar a código real.</p>
<p>Gran parte de esto viene de una intención clara: mantener el aprendizaje accesible, sin fricción y centrado en lo importante .</p>
<p>El navegador juega un papel clave aquí. Permite iterar rápido, construir con feedback real y, con el tiempo, abrir la puerta a experiencias más colaborativas.</p>
<p>Por eso estoy construyendo esto en público. No como un producto terminado, sino como algo que va tomando forma con el tiempo.</p>
<p>El proyecto es totalmente codigo abierto y puede correrse localmente. Lo puedes econtrar en <a href="https://github.com/kervin5/codoritmo">este repositorio</a>. Cualquier contribución para arreglar bugs or mejorar la funcionalidad es mas que bienvenida.</p>
<p>Después de una década en desarrollo de software, he aprendido algo simple: el razonamiento lógico sigue siendo una habilidad fundamental para cualquier programador, independientemente de las herramientas que use. Por eso este proyecto mantiene el espíritu original de PSeInt, enfocado en el pensamiento lógico, mientras también abraza nuevas formas de construir y experimentar.</p>
<p>Este es un espacio abierto para construir juntos, sin importar cómo programes. Ya sea que estés empezando y usando herramientas como IA para ayudarte, o tengas años de experiencia escribiendo todo desde cero, lo importante aquí es aprender, crear y mejorar. Las herramientas evolucionan, y la idea es disfrutar ese proceso. Si ves algo que se puede mejorar, no dudes en abrir un PR.</p>
<blockquote>
<p>Codoritmo existe gracias a PSeInt. Es una forma de reconocer ese impacto y seguir explorando nuevas maneras de aprender dentro de la web.</p>
</blockquote>
<p>Y si todo sale bien, quiza logremos ayudar a más personas a dar sus primeros pasos en el nundo de la lógica de la programación.</p>
]]></content:encoded></item><item><title><![CDATA[Cómo integrar LangChain con GPT para tareas personalizadas]]></title><description><![CDATA[1. ¿Por qué LangChain?
La librería LangChain surgió para facilitar la orquestación de modelos de lenguaje (LLM) como GPT. En lugar de pelearte con peticiones HTTP y formatos de prompts, LangChain te da piezas LEGO que puedes ensamblar para:

Encapsul...]]></description><link>https://kervin.blog/como-integrar-langchain-con-gpt-para-tareas-personalizadas</link><guid isPermaLink="true">https://kervin.blog/como-integrar-langchain-con-gpt-para-tareas-personalizadas</guid><category><![CDATA[gpt]]></category><category><![CDATA[inteligencia artificial ]]></category><category><![CDATA[langchain]]></category><category><![CDATA[Python]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Thu, 21 Aug 2025 05:47:15 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-1-por-que-langchain">1. ¿Por qué LangChain?</h2>
<p>La librería <strong>LangChain</strong> surgió para facilitar la orquestación de modelos de lenguaje (LLM) como GPT. En lugar de pelearte con peticiones HTTP y formatos de prompts, LangChain te da piezas LEGO que puedes ensamblar para:</p>
<ul>
<li>Encapsular prompts complejos.</li>
<li>Añadir memoria conversacional.</li>
<li>Conectar fuentes externas (bases de datos, APIs, archivos).</li>
<li>Diseñar cadenas (chains) reutilizables.</li>
</ul>
<hr />
<h2 id="heading-2-prerrequisitos">2. Prerrequisitos</h2>
<ol>
<li>Conocimientos básicos de Python (<code>&gt;=3.8</code>).</li>
<li>Cuenta de OpenAI y <strong>API Key</strong> válida.</li>
<li>Terminal con <code>pip</code> configurado.</li>
</ol>
<blockquote>
<p>Tip: En local basta con un editor de texto y la terminal. Si prefieres Jupyter, todos los fragmentos funcionarán sin cambios.</p>
</blockquote>
<hr />
<h2 id="heading-3-instalacion-rapida">3. Instalación rápida</h2>
<pre><code class="lang-bash"><span class="hljs-comment"># Crea un entorno virtual (opcional, pero recomendado)</span>
python -m venv .venv
<span class="hljs-built_in">source</span> .venv/bin/activate  <span class="hljs-comment"># En Windows: .venv\Scripts\activate</span>

<span class="hljs-comment"># Instala las dependencias principales</span>
pip install langchain openai python-dotenv
</code></pre>
<ul>
<li><code>langchain</code>: la orquestación.</li>
<li><code>openai</code>: cliente oficial de la API.</li>
<li><code>python-dotenv</code>: gestionará tu API Key de forma segura.</li>
</ul>
<hr />
<h2 id="heading-4-configuracion-de-la-clave-de-openai">4. Configuración de la clave de OpenAI</h2>
<pre><code class="lang-bash"><span class="hljs-comment"># Crea un archivo .env en la raíz de tu proyecto</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"OPENAI_API_KEY=tu_clave_aquí"</span> &gt; .env
</code></pre>
<p>El código leerá la variable mediante <code>dotenv</code>. Evita subir <code>.env</code> a GitHub usando <code>.gitignore</code>.</p>
<hr />
<h2 id="heading-5-tu-primer-pipeline-con-langchain-gpt">5. Tu primer pipeline con LangChain + GPT</h2>
<p>A continuación un <strong>script mínimo</strong> que pregunta al usuario y envía la consulta a GPT.</p>
<pre><code class="lang-python"><span class="hljs-comment"># archivo: my_first_chain.py</span>

<span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">from</span> langchain <span class="hljs-keyword">import</span> PromptTemplate, LLMChain
<span class="hljs-keyword">from</span> langchain.chat_models <span class="hljs-keyword">import</span> ChatOpenAI

<span class="hljs-comment"># 1) Cargar variables de entorno</span>
load_dotenv()

<span class="hljs-comment"># 2) Instanciar el modelo de lenguaje</span>
llm = ChatOpenAI(        <span class="hljs-comment"># Modelo chat-based</span>
    temperature=<span class="hljs-number">0.7</span>,     <span class="hljs-comment"># Creatividad</span>
    model_name=<span class="hljs-string">"gpt-3.5-turbo"</span>  <span class="hljs-comment"># Cambia a gpt-4 si tienes acceso</span>
)

<span class="hljs-comment"># 3) Definir el template del prompt</span>
prompt = PromptTemplate(
    input_variables=[<span class="hljs-string">"tarea"</span>],
    template=<span class="hljs-string">"""Eres un asistente experto. {tarea} En 5 puntos claros."""</span>
)

<span class="hljs-comment"># 4) Construir la chain</span>
chain = LLMChain(llm=llm, prompt=prompt)

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    consulta = input(<span class="hljs-string">"¿Qué necesitas que haga GPT? "</span>)
    respuesta = chain.run(tarea=consulta)
    print(<span class="hljs-string">"\nRespuesta:\n"</span>, respuesta)
</code></pre>
<p>Ejecuta con:</p>
<pre><code class="lang-bash">python my_first_chain.py
</code></pre>
<hr />
<h2 id="heading-6-anadiendo-memoria-chat-persistente">6. Añadiendo memoria: chat persistente</h2>
<p>Para un bot que recuerde el contexto de la conversación, usa <code>ConversationBufferMemory</code>.</p>
<pre><code class="lang-python"><span class="hljs-comment"># archivo: chat_con_memoria.py</span>

<span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
<span class="hljs-keyword">from</span> langchain.prompts <span class="hljs-keyword">import</span> ChatPromptTemplate
<span class="hljs-keyword">from</span> langchain.chains <span class="hljs-keyword">import</span> ConversationChain
<span class="hljs-keyword">from</span> langchain.chat_models <span class="hljs-keyword">import</span> ChatOpenAI
<span class="hljs-keyword">from</span> langchain.memory <span class="hljs-keyword">import</span> ConversationBufferMemory

load_dotenv()

llm = ChatOpenAI(temperature=<span class="hljs-number">0.5</span>)

<span class="hljs-comment"># Buffer en RAM (se reinicia al cerrar el programa)</span>
memoria = ConversationBufferMemory(return_messages=<span class="hljs-literal">True</span>)

chat = ConversationChain(
    llm=llm,
    memory=memoria,
    prompt=ChatPromptTemplate.from_messages([
        (<span class="hljs-string">"system"</span>, <span class="hljs-string">"Eres un tutor experto en IA."</span>),
        (<span class="hljs-string">"human"</span>, <span class="hljs-string">"{input}"</span>),
    ])
)

print(<span class="hljs-string">"Escribe 'salir' para terminar.\n"</span>)
<span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
    user_input = input(<span class="hljs-string">"Tú: "</span>)
    <span class="hljs-keyword">if</span> user_input.lower() <span class="hljs-keyword">in</span> {<span class="hljs-string">"salir"</span>, <span class="hljs-string">"exit"</span>, <span class="hljs-string">"quit"</span>}:
        <span class="hljs-keyword">break</span>
    respuesta = chat.predict(input=user_input)
    print(<span class="hljs-string">"IA:"</span>, respuesta)
</code></pre>
<hr />
<h2 id="heading-7-despliegue-ultraligero-con-fastapi">7. Despliegue ultraligero con FastAPI</h2>
<p>¿Quieres un endpoint REST? Combina FastAPI + LangChain.</p>
<pre><code class="lang-python"><span class="hljs-comment"># archivo: api_langchain.py</span>

<span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
<span class="hljs-keyword">from</span> fastapi <span class="hljs-keyword">import</span> FastAPI, HTTPException
<span class="hljs-keyword">from</span> pydantic <span class="hljs-keyword">import</span> BaseModel
<span class="hljs-keyword">from</span> langchain.llms <span class="hljs-keyword">import</span> OpenAI
<span class="hljs-keyword">from</span> langchain <span class="hljs-keyword">import</span> PromptTemplate, LLMChain

load_dotenv()

app = FastAPI(title=<span class="hljs-string">"LangChain GPT API"</span>)

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Consulta</span>(<span class="hljs-params">BaseModel</span>):</span>
    pregunta: str

llm = OpenAI(temperature=<span class="hljs-number">0.3</span>)
plantilla = PromptTemplate(
    input_variables=[<span class="hljs-string">"pregunta"</span>],
    template=<span class="hljs-string">"Responde de manera concisa: {pregunta}"</span>
)
chain = LLMChain(llm=llm, prompt=plantilla)

<span class="hljs-meta">@app.post("/preguntar")</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">preguntar</span>(<span class="hljs-params">body: Consulta</span>):</span>
    <span class="hljs-keyword">try</span>:
        respuesta = chain.run(pregunta=body.pregunta)
        <span class="hljs-keyword">return</span> {<span class="hljs-string">"respuesta"</span>: respuesta.strip()}
    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
        <span class="hljs-keyword">raise</span> HTTPException(status_code=<span class="hljs-number">500</span>, detail=str(e))
</code></pre>
<pre><code class="lang-bash">pip install fastapi uvicorn  <span class="hljs-comment"># Si aún no los tienes</span>
uvicorn api_langchain:app --reload
</code></pre>
<p>Ya tienes un servicio que acepta <code>POST /preguntar</code> con JSON <code>{ "pregunta": "..." }</code>.</p>
<hr />
<h2 id="heading-8-errores-frecuentes-y-como-solucionarlos">8. Errores frecuentes y cómo solucionarlos</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Error</td><td>Causa</td><td>Solución rápida</td></tr>
</thead>
<tbody>
<tr>
<td><code>openai.error.AuthenticationError</code></td><td>Clave de API ausente o mal escrita</td><td>Verifica <code>.env</code> y que la variable sea <code>OPENAI_API_KEY</code></td></tr>
<tr>
<td><code>RateLimitError</code></td><td>Exceso de peticiones</td><td>Implementa backoff o sube de plan</td></tr>
<tr>
<td>Respuesta vacía</td><td>Prompt mal formado</td><td>Revisa <code>input_variables</code> y placeholders</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-9-buenas-practicas">9. Buenas prácticas</h2>
<ul>
<li>Usa <strong>temperatura baja</strong> para tareas deterministas.</li>
<li>Almacena logs de prompts y respuestas para depurar.</li>
<li>Reserva <code>system</code> prompts para fijar el tono y rol del asistente.</li>
<li>Si tu aplicación es multi-usuario, combina <code>ConversationBufferMemory</code> con un identificador de sesión.</li>
</ul>
<hr />
<h2 id="heading-10-recursos-adicionales">10. Recursos adicionales</h2>
<ul>
<li>Documentación oficial de LangChain: <a target="_blank" href="https://python.langchain.com/">https://python.langchain.com/</a></li>
<li>API Reference de OpenAI: <a target="_blank" href="https://platform.openai.com/docs">https://platform.openai.com/docs</a></li>
<li>Ejemplos de producción (repos públicos):<ul>
<li><a target="_blank" href="https://github.com/hwchase17/langchain-hub">https://github.com/hwchase17/langchain-hub</a></li>
</ul>
</li>
<li>Tutoriales complementarios (en español):<ul>
<li><a target="_blank" href="https://youtu.be/6xAl-6V2YEQ">https://youtu.be/6xAl-6V2YEQ</a></li>
</ul>
</li>
</ul>
<hr />
<p>¡Listo! Con estas bases ya puedes construir asistentes, buscadores inteligentes o cualquier flujo personalizado usando LangChain y GPT. Aprovecha el código como plantilla y adapta los prompts a tu caso de uso.</p>
]]></content:encoded></item><item><title><![CDATA[Cómo reducir el tamaño de un modelo LLM usando quantization]]></title><description><![CDATA[Qué es la quantization y por qué te importa
La quantization consiste en representar los pesos y activaciones del modelo con menos bits (8-bit, 4-bit, etc.) en lugar de usar formatos flotantes de 16/32 bits. Al hacerlo se consiguen:

Modelos 2-8× más ...]]></description><link>https://kervin.blog/como-reducir-el-tamano-de-un-modelo-llm-usando-quantization</link><guid isPermaLink="true">https://kervin.blog/como-reducir-el-tamano-de-un-modelo-llm-usando-quantization</guid><category><![CDATA[Optimización]]></category><category><![CDATA[llm]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[quantization]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Thu, 21 Aug 2025 05:44:30 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-que-es-la-quantization-y-por-que-te-importa">Qué es la quantization y por qué te importa</h2>
<p>La quantization consiste en representar los pesos y activaciones del modelo con menos bits (8-bit, 4-bit, etc.) en lugar de usar formatos flotantes de 16/32 bits. Al hacerlo se consiguen:</p>
<ul>
<li>Modelos 2-8× más pequeños (caben en GPUs de menor VRAM o incluso en CPU).</li>
<li>Menor consumo de memoria y energía.</li>
<li>Inferencia más rápida gracias a operaciones de menor precisión.</li>
</ul>
<p>El precio a pagar es una posible (y normalmente pequeña) pérdida de precisión, que puede mitigarse con las técnicas correctas.</p>
<h2 id="heading-requisitos-previos">Requisitos previos</h2>
<ul>
<li>Conocimientos básicos de Python y PyTorch.</li>
<li>Una GPU con soporte CUDA (opcional pero recomendado).</li>
<li>Python ≥ 3.8.</li>
<li>Paquetes: <code>transformers</code>, <code>bitsandbytes</code>, <code>accelerate</code>.</li>
</ul>
<pre><code class="lang-bash">pip install -U transformers bitsandbytes accelerate
</code></pre>
<h2 id="heading-3-caminos-de-quantization">3 caminos de quantization</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Estrategia</td><td>Cuándo usarla</td><td>Ventajas</td><td>Desventajas</td></tr>
</thead>
<tbody>
<tr>
<td>Post-Training Quantization (PTQ)</td><td>Quieres cuantizar un modelo ya entrenado, sin volver a entrenar.</td><td>Rápida y simple.</td><td>Puede perder más precisión.</td></tr>
<tr>
<td>Quantization Aware Training (QAT)</td><td>Tienes acceso al proceso de entrenamiento.</td><td>Precisión casi idéntica al FP16.</td><td>Necesita entrenar otra vez.</td></tr>
<tr>
<td>Hybrid / Layer-wise</td><td>Mezcla capas cuantizadas y en alta precisión.</td><td>Control fino del trade-off.</td><td>Complejo de ajustar.</td></tr>
</tbody>
</table>
</div><p>En esta guía usaremos PTQ de 4-bit con bitsandbytes porque ofrece el mejor balance entre simplicidad y calidad.</p>
<h2 id="heading-paso-a-paso-cuantizar-en-4-bit-con-bitsandbytes">Paso a paso: cuantizar en 4-bit con bitsandbytes</h2>
<pre><code class="lang-python"><span class="hljs-comment"># quantize_llm.py</span>
<span class="hljs-comment"># Cuantiza un modelo existente a 4 bits de forma inmediata.</span>

<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModelForCausalLM, AutoTokenizer
<span class="hljs-keyword">import</span> torch

<span class="hljs-comment"># 1) Identificador del modelo en Hugging Face</span>
model_id = <span class="hljs-string">'facebook/opt-1.3b'</span>  <span class="hljs-comment"># ~2.7 GB en FP16</span>

<span class="hljs-comment"># 2) Cargamos el modelo directamente en 4-bit</span>
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    load_in_4bit=<span class="hljs-literal">True</span>,      <span class="hljs-comment"># Activa la cuantización</span>
    device_map=<span class="hljs-string">'auto'</span>,      <span class="hljs-comment"># Aprovecha todas las GPUs/CPU disponibles</span>
    quantization_config={
        <span class="hljs-string">'bnb_4bit_compute_dtype'</span>: torch.bfloat16,  <span class="hljs-comment"># Precisión de cálculo</span>
        <span class="hljs-string">'bnb_4bit_use_double_quant'</span>: <span class="hljs-literal">True</span>,         <span class="hljs-comment"># Segunda cuantización para más calidad</span>
        <span class="hljs-string">'bnb_4bit_quant_type'</span>: <span class="hljs-string">'nf4'</span>               <span class="hljs-comment"># Normal-Float4, mejor que int4</span>
    }
)

tokenizer = AutoTokenizer.from_pretrained(model_id)

<span class="hljs-comment"># 3) Inferencia de prueba</span>
prompt = <span class="hljs-string">'Dame 3 consejos para aprender machine learning:'</span>
inputs = tokenizer(prompt, return_tensors=<span class="hljs-string">'pt'</span>).to(model.device)
<span class="hljs-keyword">with</span> torch.no_grad():
    outputs = model.generate(**inputs, max_new_tokens=<span class="hljs-number">100</span>)

print(tokenizer.decode(outputs[<span class="hljs-number">0</span>], skip_special_tokens=<span class="hljs-literal">True</span>))
</code></pre>
<p>Resultado típico:</p>
<ul>
<li>Tamaño en disco: de 2.7 GB a ~700 MB.</li>
<li>VRAM utilizada: ≈4 GB al inferir.</li>
<li>Latencia: 20-40 % más rápida (dependiendo del hardware).</li>
</ul>
<h2 id="heading-verificar-la-degradacion-de-calidad">Verificar la degradación de calidad</h2>
<p>Cuantizar sin medir es apostar a ciegas. Dos métricas rápidas:</p>
<ol>
<li>Perplejidad (modelos de lenguaje)</li>
<li>Exactitud en tareas de benchmark (ej. MMLU, GSM8K)</li>
</ol>
<p>Ejemplo con <code>evaluate</code>:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> evaluate <span class="hljs-keyword">import</span> load
<span class="hljs-keyword">import</span> torch

perplexity = load(<span class="hljs-string">'perplexity'</span>, module_type=<span class="hljs-string">'metric'</span>)
score = perplexity.compute(
    model_id=<span class="hljs-string">'facebook/opt-1.3b'</span>,
    add_start_token=<span class="hljs-literal">True</span>,
    device=torch.device(<span class="hljs-string">'cuda'</span> <span class="hljs-keyword">if</span> torch.cuda.is_available() <span class="hljs-keyword">else</span> <span class="hljs-string">'cpu'</span>)
)
print(<span class="hljs-string">'Perplejidad original:'</span>, score[<span class="hljs-string">'perplexities'</span>][<span class="hljs-number">0</span>])

score_q = perplexity.compute(
    model=model,  <span class="hljs-comment"># modelo cuantizado</span>
    tokenizer=tokenizer,
    add_start_token=<span class="hljs-literal">True</span>,
)
print(<span class="hljs-string">'Perplejidad 4-bit:'</span>, score_q[<span class="hljs-string">'perplexities'</span>][<span class="hljs-number">0</span>])
</code></pre>
<p>Regla práctica: si la métrica empeora menos de 5 %, la cuantización es “gratis” para producción.</p>
<h2 id="heading-ajustes-finos-con-quantization-aware-training">Ajustes finos con Quantization Aware Training</h2>
<p>Si el modelo pierde demasiado rendimiento:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Idea general (no runnable): inserta capas fake-quant durante el fine-tuning</span>
<span class="hljs-keyword">from</span> torch.ao.quantization <span class="hljs-keyword">import</span> get_default_qat_qconfig, prepare_qat, convert

model.train()
model.qconfig = get_default_qat_qconfig(<span class="hljs-string">'fbgemm'</span>)
model_prepared = prepare_qat(model)
<span class="hljs-comment"># ... continúa tu entrenamiento ...</span>
model_int8 = convert(model_prepared)  <span class="hljs-comment"># Modelo listo en 8-bit</span>
</code></pre>
<p>QAT requiere más tiempo de entrenamiento pero recupera casi toda la precisión original.</p>
<h2 id="heading-otros-formatos-y-herramientas-populares">Otros formatos y herramientas populares</h2>
<ul>
<li>GPTQ / Auto-GPTQ – apropiado para despliegue en CPU.</li>
<li>GGML / GGUF – ideal para dispositivos móviles o Raspberry Pi.</li>
<li>TensorRT-LLM – quantization + optimización para GPU NVIDIA.</li>
<li>Intel Neural Compressor – simplifica PTQ y QAT en hardware Intel.</li>
</ul>
<h2 id="heading-errores-comunes-y-como-evitarlos">Errores comunes y cómo evitarlos</h2>
<ol>
<li>Mezclar capas de precisión distinta sin fijar <code>torch.autocast</code>: produce overflows.</li>
<li>Olvidar el <code>to(model.device)</code> en la tokenización: el modelo funciona pero más lento.</li>
<li>Cuantizar embeddings de entrada en tareas de clasificación pequeñas: suelen perder precisión desproporcionada; usa formato mixto (embeddings en FP16).</li>
</ol>
<h2 id="heading-checklist-rapida-antes-de-subir-a-produccion">Checklist rápida antes de subir a producción</h2>
<ul>
<li>[ ] La métrica clave baja &lt; 5 %.</li>
<li>[ ] No aparecen mensajes de overflow/underflow en logs.</li>
<li>[ ] El modelo cabe en la memoria estimada con margen del 10 %.</li>
<li>[ ] Latencia medida con <code>torch.cuda.synchronize()</code> es aceptable.</li>
<li>[ ] Se guarda copia del modelo original por si hay que revertir.</li>
</ul>
<h2 id="heading-recursos-recomendados">Recursos recomendados</h2>
<ul>
<li>Paper “SmoothQuant” (OpenAI &amp; Microsoft) – mejora PTQ en Transformers.</li>
<li>Guía oficial de bitsandbytes: https://github.com/TimDettmers/bitsandbytes</li>
<li>Cheat-sheet de Hugging Face para quantization: https://huggingface.co/docs/transformers/perf_quantization</li>
</ul>
<p>¡Listo! Ahora tienes un LLM más ligero que cabe en tu hardware y responde más rápido, sin sacrificar calidad de manera significativa.</p>
]]></content:encoded></item><item><title><![CDATA[Crear tu primer Chatbot con LangChain y OpenAI]]></title><description><![CDATA[¿Por qué LangChain?
LangChain es una librería de orquestación que simplifica la creación de aplicaciones que usan modelos de lenguaje (LLMs). En lugar de lidiar con peticiones HTTP directas a la API de OpenAI, te ofrece:

Componentes reutilizables: p...]]></description><link>https://kervin.blog/crear-tu-primer-chatbot-con-langchain-y-openai</link><guid isPermaLink="true">https://kervin.blog/crear-tu-primer-chatbot-con-langchain-y-openai</guid><category><![CDATA[#chatbots]]></category><category><![CDATA[langchain]]></category><category><![CDATA[openai]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Thu, 21 Aug 2025 05:43:14 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-por-que-langchain">¿Por qué LangChain?</h2>
<p>LangChain es una <strong>librería de orquestación</strong> que simplifica la creación de aplicaciones que usan modelos de lenguaje (LLMs). En lugar de lidiar con peticiones HTTP directas a la API de OpenAI, te ofrece:</p>
<ul>
<li>Componentes reutilizables: prompts, cadenas de llamadas, memorias.</li>
<li>Abstracciones para integrar bases de datos, buscadores, archivos, etc.</li>
<li>Un ecosistema en rápido crecimiento que permite escalar tu idea en minutos.</li>
</ul>
<hr />
<h2 id="heading-requisitos-previos">Requisitos previos</h2>
<ol>
<li>Conocimientos básicos de Python ≥ 3.8.</li>
<li>Una cuenta en OpenAI con créditos activos.</li>
<li>Terminal de comandos (macOS/Linux) o PowerShell (Windows).</li>
</ol>
<hr />
<h2 id="heading-paso-1-consigue-y-protege-tu-clave-de-openai">Paso 1. Consigue y protege tu clave de OpenAI</h2>
<ol>
<li>Entra en <a target="_blank" href="https://platform.openai.com/account/api-keys">https://platform.openai.com/account/api-keys</a> y genera una nueva clave.</li>
<li>Guarda la cadena en un gestor de contraseñas o variable de entorno; <strong>no</strong> la subas a GitHub.</li>
</ol>
<p>Ejemplo de archivo <code>.env</code> (agrega en la raíz del proyecto):</p>
<pre><code class="lang-bash">OPENAI_API_KEY=<span class="hljs-string">"tu_clave_aquí"</span>
</code></pre>
<hr />
<h2 id="heading-paso-2-prepara-el-entorno-de-trabajo">Paso 2. Prepara el entorno de trabajo</h2>
<pre><code class="lang-bash"><span class="hljs-comment"># 1. Crea y activa un entorno virtual</span>
python -m venv .venv
<span class="hljs-built_in">source</span> .venv/bin/activate  <span class="hljs-comment"># Windows: .venv\Scripts\activate</span>

<span class="hljs-comment"># 2. Actualiza pip</span>
pip install --upgrade pip
</code></pre>
<hr />
<h2 id="heading-paso-3-instala-las-dependencias">Paso 3. Instala las dependencias</h2>
<pre><code class="lang-bash">pip install langchain openai python-dotenv
</code></pre>
<ul>
<li><code>langchain</code>: la estrella del tutorial.</li>
<li><code>openai</code>: cliente oficial de OpenAI (LangChain lo usa internamente).</li>
<li><code>python-dotenv</code>: carga la variable <code>OPENAI_API_KEY</code> desde el archivo <code>.env</code>.</li>
</ul>
<hr />
<h2 id="heading-paso-4-codigo-minimo-viable-del-chatbot">Paso 4. Código mínimo viable del chatbot</h2>
<p>Crea <code>chatbot.py</code>:</p>
<pre><code class="lang-python"><span class="hljs-string">"""chatbot.py
Chatbot de consola usando LangChain + OpenAI.
"""</span>
<span class="hljs-keyword">from</span> langchain.chat_models <span class="hljs-keyword">import</span> ChatOpenAI
<span class="hljs-keyword">from</span> langchain.schema <span class="hljs-keyword">import</span> (SystemMessage, HumanMessage)
<span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
<span class="hljs-keyword">import</span> os

<span class="hljs-comment"># Carga la variable OPENAI_API_KEY desde .env</span>
env_path = os.path.join(os.path.dirname(__file__), <span class="hljs-string">'.env'</span>)
load_dotenv(env_path)

<span class="hljs-comment"># 1️⃣ Configura el modelo de chat</span>
chat = ChatOpenAI(
    model_name=<span class="hljs-string">"gpt-3.5-turbo"</span>,  <span class="hljs-comment"># Cambia a gpt-4 si tu cuenta lo permite</span>
    temperature=<span class="hljs-number">0.7</span>,             <span class="hljs-comment"># 0 = respuestas más deterministas, 1 = más creativas</span>
    streaming=<span class="hljs-literal">True</span>               <span class="hljs-comment"># Muestra tokens en tiempo real</span>
)

<span class="hljs-comment"># 2️⃣ Mensaje de sistema: define la personalidad del bot</span>
system_message = SystemMessage(
    content=<span class="hljs-string">"Eres un asistente experto en recetas de cocina latina."</span>
)

print(<span class="hljs-string">"\n🤖  Bot listo. Escribe 'salir' para terminar.\n"</span>)

<span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
    user_input = input(<span class="hljs-string">"Tú: "</span>)
    <span class="hljs-keyword">if</span> user_input.lower() <span class="hljs-keyword">in</span> {<span class="hljs-string">"salir"</span>, <span class="hljs-string">"exit"</span>, <span class="hljs-string">"quit"</span>}:
        <span class="hljs-keyword">break</span>

    <span class="hljs-comment"># 3️⃣ Crea el mensaje del usuario</span>
    human_message = HumanMessage(content=user_input)

    <span class="hljs-comment"># 4️⃣ Llama al modelo</span>
    response = chat([system_message, human_message])

    <span class="hljs-comment"># 5️⃣ Muestra la respuesta del bot</span>
    print(<span class="hljs-string">f"\n🤖: <span class="hljs-subst">{response.content}</span>\n"</span>)
</code></pre>
<p>Ejecuta:</p>
<pre><code class="lang-bash">python chatbot.py
</code></pre>
<p>¡Listo! Tienes un chatbot especializado en recetas latinas funcionando en tu terminal.</p>
<hr />
<h2 id="heading-paso-5-anade-memoria-de-conversacion">Paso 5. Añade memoria de conversación</h2>
<p>El script anterior no recuerda mensajes anteriores. LangChain lo soluciona con <code>ConversationBufferMemory</code> y <code>ConversationChain</code>.</p>
<pre><code class="lang-python"><span class="hljs-comment"># memoria_chatbot.py</span>
<span class="hljs-keyword">from</span> langchain.chat_models <span class="hljs-keyword">import</span> ChatOpenAI
<span class="hljs-keyword">from</span> langchain.chains <span class="hljs-keyword">import</span> ConversationChain
<span class="hljs-keyword">from</span> langchain.memory <span class="hljs-keyword">import</span> ConversationBufferMemory
<span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
<span class="hljs-keyword">import</span> os

load_dotenv()

llm = ChatOpenAI(temperature=<span class="hljs-number">0.7</span>)

<span class="hljs-comment"># Almacena el historial completo en RAM</span>
memory = ConversationBufferMemory(return_messages=<span class="hljs-literal">True</span>)

conversation = ConversationChain(
    llm=llm,
    memory=memory,
    verbose=<span class="hljs-literal">False</span>  <span class="hljs-comment"># True para depurar</span>
)

print(<span class="hljs-string">"\n🤖  Memoria activada. Escribe 'salir' para terminar.\n"</span>)
<span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
    user_input = input(<span class="hljs-string">"Tú: "</span>)
    <span class="hljs-keyword">if</span> user_input.lower() == <span class="hljs-string">"salir"</span>:
        <span class="hljs-keyword">break</span>

    <span class="hljs-comment"># LangChain gestiona la conversación internamente</span>
    response = conversation.predict(input=user_input)
    print(<span class="hljs-string">f"\n🤖: <span class="hljs-subst">{response}</span>\n"</span>)
</code></pre>
<p>Beneficios:</p>
<ul>
<li>El bot recuerda el contexto y puede dar respuestas coherentes en diálogos largos.</li>
<li>Podrás almacenar la memoria en bases de datos o vectores con cambios mínimos.</li>
</ul>
<hr />
<h2 id="heading-paso-6-personaliza-prompts-y-herramientas">Paso 6. Personaliza prompts y herramientas</h2>
<p>LangChain permite enriquecer tu bot con:</p>
<ol>
<li>Prompts más complejos (<code>ChatPromptTemplate</code>).</li>
<li>Herramientas externas (<code>llm-math</code>, Google Search, APIs propias).</li>
<li>Cadenas (Chains) como <code>RetrievalQA</code> para conectarte a un índice de documentos.</li>
</ol>
<p>Ejemplo sencillo de prompt template:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> langchain.prompts <span class="hljs-keyword">import</span> ChatPromptTemplate
<span class="hljs-keyword">from</span> langchain.chat_models <span class="hljs-keyword">import</span> ChatOpenAI

model = ChatOpenAI()

prompt = ChatPromptTemplate.from_messages([
    (<span class="hljs-string">"system"</span>, <span class="hljs-string">"Eres un bot que traduce español a inglés."</span>),
    (<span class="hljs-string">"human"</span>, <span class="hljs-string">"{texto_es}"</span>)
])

print(prompt.format(texto_es=<span class="hljs-string">"¿Cómo estás?"</span>))
<span class="hljs-comment"># --&gt; {'role': 'human', 'content': '¿Cómo estás?'}</span>

response = model(prompt.format_messages(texto_es=<span class="hljs-string">"¿Cómo estás?"</span>))
print(response.content)
</code></pre>
<hr />
<h2 id="heading-paso-7-despliegue-rapido-como-api">Paso 7. Despliegue rápido como API</h2>
<p>Usa <strong>FastAPI</strong> para exponer tu chatbot en la web.</p>
<pre><code class="lang-bash">pip install fastapi uvicorn[standard]
</code></pre>
<p><code>app.py</code>:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> fastapi <span class="hljs-keyword">import</span> FastAPI, HTTPException
<span class="hljs-keyword">from</span> pydantic <span class="hljs-keyword">import</span> BaseModel
<span class="hljs-keyword">from</span> langchain.chat_models <span class="hljs-keyword">import</span> ChatOpenAI
<span class="hljs-keyword">from</span> langchain.memory <span class="hljs-keyword">import</span> ConversationBufferMemory
<span class="hljs-keyword">from</span> langchain.chains <span class="hljs-keyword">import</span> ConversationChain
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv

load_dotenv()

app = FastAPI()

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Msg</span>(<span class="hljs-params">BaseModel</span>):</span>
    session_id: str
    text: str

<span class="hljs-comment"># Un diccionario simple de memorias por sesión</span>
active_sessions = {}

<span class="hljs-meta">@app.post("/chat")</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">chat_endpoint</span>(<span class="hljs-params">msg: Msg</span>):</span>
    <span class="hljs-keyword">if</span> msg.session_id <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> active_sessions:
        active_sessions[msg.session_id] = ConversationChain(
            llm=ChatOpenAI(),
            memory=ConversationBufferMemory(return_messages=<span class="hljs-literal">True</span>)
        )

    conversation = active_sessions[msg.session_id]
    <span class="hljs-keyword">try</span>:
        response = conversation.predict(input=msg.text)
        <span class="hljs-keyword">return</span> {<span class="hljs-string">"answer"</span>: response}
    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
        <span class="hljs-keyword">raise</span> HTTPException(status_code=<span class="hljs-number">500</span>, detail=str(e))
</code></pre>
<p>Lanza el servidor:</p>
<pre><code class="lang-bash">uvicorn app:app --reload --port 8000
</code></pre>
<p>Ahora realiza peticiones <code>POST</code> a <code>http://localhost:8000/chat</code> con cualquier herramienta REST.</p>
<hr />
<h2 id="heading-buenas-practicas-finales">Buenas prácticas finales</h2>
<ol>
<li>Limita el número de tokens para reducir costos (<code>max_tokens</code>).</li>
<li>Usa <code>retry</code> y <code>timeout</code> para lidiar con errores de red.</li>
<li>Cifra y guarda tu clave en variables seguras en producción.</li>
<li>Versiona tus prompts como parte del código.</li>
<li>Mide el uso con los dashboards de OpenAI o tu propia analítica.</li>
</ol>
<hr />
<h2 id="heading-proximos-pasos-sugeridos">Próximos pasos sugeridos</h2>
<ul>
<li>Conectar un motor de vectores (Weaviate, Pinecone) y usar <code>RetrievalQA</code> para un bot basado en tus documentos.</li>
<li>Añadir autenticación JWT a la API.</li>
<li>Desplegar en plataformas serverless (Vercel, AWS Lambda, Google Cloud Run).</li>
</ul>
<p>¡Ya tienes la base para explorar el enorme ecosistema de LangChain y crear chatbots más potentes y especializados!</p>
]]></content:encoded></item><item><title><![CDATA[Por qué `NaN` no es igual a `NaN` y otras rarezas de JavaScript 🚩]]></title><description><![CDATA[En el mundo de la programación, JavaScript está lleno de sorpresas y peculiaridades que pueden confundir incluso a los desarrolladores más experimentados. Una de esas rarezas es el comportamiento del identificador NaN. ¿Alguna vez te has preguntado p...]]></description><link>https://kervin.blog/por-que-nan-no-es-igual-a-nan-y-otras-rarezas-de-javascript</link><guid isPermaLink="true">https://kervin.blog/por-que-nan-no-es-igual-a-nan-y-otras-rarezas-de-javascript</guid><category><![CDATA[NaN en JavaScript]]></category><category><![CDATA[Rarezas de JavaScript]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Thu, 21 Aug 2025 05:26:45 GMT</pubDate><content:encoded><![CDATA[<p>En el mundo de la programación, JavaScript está lleno de sorpresas y peculiaridades que pueden confundir incluso a los desarrolladores más experimentados. Una de esas rarezas es el comportamiento del identificador <code>NaN</code>. ¿Alguna vez te has preguntado por qué <code>NaN</code> no es igual a <code>NaN</code>? Aquí te lo explicamos.</p>
<h2 id="heading-que-es-nan">¿Qué es <code>NaN</code>?</h2>
<p><code>NaN</code> significa "Not-a-Number" (no es un número) y es un valor especial en JavaScript que representa un resultado de operación numérica indefinida o fallida. Algunas operaciones que producen <code>NaN</code> son dividir un número por cero o convertir una cadena no numérica en un número.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-number">0</span> / <span class="hljs-number">0</span>); <span class="hljs-comment">// NaN</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">parseInt</span>(<span class="hljs-string">'hello'</span>)); <span class="hljs-comment">// NaN</span>
</code></pre>
<h2 id="heading-por-que-nan-no-es-igual-a-nan">¿Por qué <code>NaN</code> no es igual a <code>NaN</code>?</h2>
<p>En JavaScript, <code>NaN</code> es el único valor que no es igual a sí mismo. Esta es una propiedad definida por el estándar IEEE 754 para aritmética de punto flotante. La lógica detrás de esto es que <code>NaN</code> es un resultado indeterminado, por lo tanto, cualquier comparación entre dos valores <code>NaN</code> también debe ser indeterminada.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-literal">NaN</span> == <span class="hljs-literal">NaN</span>); <span class="hljs-comment">// false</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-literal">NaN</span> === <span class="hljs-literal">NaN</span>); <span class="hljs-comment">// false</span>
</code></pre>
<p>Para verificar si un valor es <code>NaN</code>, JavaScript proporciona la función <code>isNaN()</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">isNaN</span>(<span class="hljs-literal">NaN</span>)); <span class="hljs-comment">// true</span>
</code></pre>
<h2 id="heading-otras-rarezas-de-javascript">Otras rarezas de JavaScript</h2>
<h3 id="heading-1-coercion-de-tipos">1. Coerción de tipos</h3>
<p>Una de las características más desconcertantes de JavaScript es su coerción de tipos automática. Por ejemplo:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'5'</span> + <span class="hljs-number">3</span>); <span class="hljs-comment">// "53"</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'5'</span> - <span class="hljs-number">3</span>); <span class="hljs-comment">// 2</span>
</code></pre>
<h3 id="heading-2-comparaciones-curiosas">2. Comparaciones curiosas</h3>
<p>El comportamiento de las comparaciones en JavaScript puede ser sorprendente:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-number">0</span> == <span class="hljs-literal">false</span>); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-number">0</span> === <span class="hljs-literal">false</span>); <span class="hljs-comment">// false</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-literal">null</span> == <span class="hljs-literal">undefined</span>); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-literal">null</span> === <span class="hljs-literal">undefined</span>); <span class="hljs-comment">// false</span>
</code></pre>
<h3 id="heading-3-variables-hoisting">3. Variables hoisting</h3>
<p>En JavaScript, las declaraciones de variables son "hoisted" al inicio de su contexto de ejecución:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(myVar); <span class="hljs-comment">// undefined</span>
<span class="hljs-keyword">var</span> myVar = <span class="hljs-number">5</span>;
</code></pre>
<p>Esto es porque la declaración <code>var myVar;</code> se mueve al inicio de su función o contexto global, pero su asignación <code>= 5</code> no.</p>
<h2 id="heading-conclusiones">Conclusiones</h2>
<p>JavaScript es un lenguaje poderoso pero a veces ilógico para los que no lo conocen en profundidad. Entender estas rarezas no solo te ayudará a evitar errores sino también a escribir un código más limpio y eficiente.</p>
<p>Si este artículo te aclaró alguna duda o te hizo reír con estas peculiaridades, ¡compártelo con otros desarrolladores curiosos y sigue explorando el fascinante mundo de JavaScript!</p>
]]></content:encoded></item><item><title><![CDATA[Diferencia entre `null` y `undefined` explicada para humanos]]></title><description><![CDATA[Si alguna vez te has encontrado con null y undefined en JavaScript y te has preguntado cuáles son las diferencias reales entre ambos, no estás solo. Estos conceptos pueden ser confusos al principio, pero una vez que conoces sus particularidades, se v...]]></description><link>https://kervin.blog/diferencia-entre-null-y-undefined-explicada-para-humanos</link><guid isPermaLink="true">https://kervin.blog/diferencia-entre-null-y-undefined-explicada-para-humanos</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Null]]></category><category><![CDATA[Programación]]></category><category><![CDATA[undefined]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Wed, 20 Aug 2025 01:56:52 GMT</pubDate><content:encoded><![CDATA[<p>Si alguna vez te has encontrado con <code>null</code> y <code>undefined</code> en JavaScript y te has preguntado cuáles son las diferencias reales entre ambos, no estás solo. Estos conceptos pueden ser confusos al principio, pero una vez que conoces sus particularidades, se vuelven bastante manejables.</p>
<h2 id="heading-entendiendo-undefined">Entendiendo <code>undefined</code></h2>
<p><code>undefined</code> es un término que básicamente significa "no asignado". En JavaScript, una variable es <code>undefined</code> cuando se ha declarado pero no se le ha asignado ningún valor. Aquí tienes un ejemplo:</p>
<pre><code class="lang-javascript">grafo
<span class="hljs-keyword">let</span> valor;
<span class="hljs-built_in">console</span>.log(valor); <span class="hljs-comment">// Imprime 'undefined'</span>
</code></pre>
<p>En este caso, <code>valor</code> es una variable a la que no se le ha dado ningún valor, por lo tanto, JavaScript le asigna automáticamente <code>undefined</code>.</p>
<p>Otro caso donde puedes encontrar <code>undefined</code> es cuando intentas acceder a una propiedad de un objeto que no existe:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> objeto = {};
<span class="hljs-built_in">console</span>.log(objeto.propiedadInexistente); <span class="hljs-comment">// Imprime 'undefined'</span>
</code></pre>
<h2 id="heading-explorando-null">Explorando <code>null</code></h2>
<p><code>null</code>, por otro lado, es un valor que un programador puede asignar intencionalmente a una variable. Representa la ausencia intencionada de un valor. A diferencia de <code>undefined</code>, tienes el control total sobre cuándo y dónde usar <code>null</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> valorVacio = <span class="hljs-literal">null</span>;
<span class="hljs-built_in">console</span>.log(valorVacio); <span class="hljs-comment">// Imprime 'null'</span>
</code></pre>
<p>En este caso, <code>valorVacio</code> ha sido explícitamente asignado a <code>null</code>, indicando que no tiene valor, pero esta falta de valor es deliberada.</p>
<h2 id="heading-resumen-clave">Resumen Clave</h2>
<p>Aquí te dejo un resumen rápido para recordar:</p>
<ul>
<li><strong><code>undefined</code></strong>: JavaScript lo asigna cuando una variable se declara pero no se inicializa, o cuando una propiedad no existe.</li>
<li><strong><code>null</code></strong>: Asignado intencionalmente por el programador para indicar que una variable no tiene valor.</li>
</ul>
<h2 id="heading-por-que-es-importante-conocer-la-diferencia">¿Por qué es importante conocer la diferencia?</h2>
<p>Distinguir adecuadamente entre <code>null</code> y <code>undefined</code> ayuda a evitar errores comunes al manejar datos en JavaScript y es crucial para escribir código limpio y fácil de entender. También mejora tu habilidad para depurar problemas potenciales en el código más rápidamente.</p>
<p>La próxima vez que te encuentres lidiando con <code>null</code> o <code>undefined</code>, recuerda que uno es el resultado de no haber hecho nada (¡aún!), mientras que el otro es el resultado de una decisión deliberada.</p>
<p>Mantener tu código claro sobre cómo y cuándo usar cada uno hará que tu vida como desarrollador sea mucho más fácil.</p>
]]></content:encoded></item><item><title><![CDATA[Cómo filtrar elementos de un array en JavaScript sin morir en el intento]]></title><description><![CDATA[En JavaScript, trabajar con arrays es como cocinar: puedes tener todos los ingredientes (datos) que necesitas, pero si no sabes cómo separarlos bien, ¡terminarás con un desastre en la cocina! Hoy veremos cómo usar .filter() para quedarte solo con los...]]></description><link>https://kervin.blog/como-filtrar-elementos-de-un-array-en-javascript-sin-morir-en-el-intento</link><guid isPermaLink="true">https://kervin.blog/como-filtrar-elementos-de-un-array-en-javascript-sin-morir-en-el-intento</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[array]]></category><category><![CDATA[Filter]]></category><category><![CDATA[arreglos]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Desarrollo Web]]></category><category><![CDATA[webdev]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Mon, 14 Oct 2024 00:52:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728867067463/846c45ec-5e57-4e98-b761-cb63ef265add.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>En JavaScript, trabajar con arrays es como cocinar: puedes tener todos los ingredientes (datos) que necesitas, pero si no sabes cómo separarlos bien, ¡terminarás con un desastre en la cocina! Hoy veremos cómo usar <code>.filter()</code> para quedarte solo con los elementos que te interesan, ¡y dejar todo lo demás fuera!</p>
<h3 id="heading-que-es-filter">¿Qué es <code>.filter()</code>?</h3>
<p>La función <code>.filter()</code> es como un colador mágico en la programación. Te permite seleccionar los elementos de un array que cumplan con una condición específica. Digamos que tienes una caja de donas, pero solo quieres las de chocolate (buen gusto). Usas <code>.filter()</code> para quedarte solo con esas delicias chocolatosas y olvidarte del resto.</p>
<h3 id="heading-sintaxis-basica">Sintaxis básica</h3>
<pre><code class="lang-javascript">javascriptCopy codeconst nuevoArray = arrayOriginal.filter(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">elemento</span>) </span>{
  <span class="hljs-comment">// condición que debe cumplir</span>
  <span class="hljs-keyword">return</span> condición;
});
</code></pre>
<h3 id="heading-ejemplo-sencillo-filtrando-numeros-pares">Ejemplo sencillo: Filtrando números pares</h3>
<p>Imagina que tienes una lista de números y solo te interesan los números pares (porque te gustan las cosas simétricas).</p>
<pre><code class="lang-javascript">javascriptCopy codeconst numeros = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">10</span>];
<span class="hljs-keyword">const</span> pares = numeros.filter(<span class="hljs-function"><span class="hljs-params">num</span> =&gt;</span> num % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>);

<span class="hljs-built_in">console</span>.log(pares); <span class="hljs-comment">// [2, 4, 6, 8, 10]</span>
</code></pre>
<p>Aquí, <code>num % 2 === 0</code> es la condición: si el número es divisible entre 2 sin residuo, ¡es un número par!</p>
<h3 id="heading-ejemplo-2-filtrando-objetos-en-un-array">Ejemplo 2: Filtrando objetos en un array</h3>
<p>No solo puedes filtrar números o strings, ¡también puedes hacerlo con objetos! Imagina que tienes una lista de personas y solo te interesan los que tienen más de 18 años para un club exclusivo (nada de menores aquí).</p>
<pre><code class="lang-javascript">javascriptCopy codeconst personas = [
  { <span class="hljs-attr">nombre</span>: <span class="hljs-string">'Ana'</span>, <span class="hljs-attr">edad</span>: <span class="hljs-number">15</span> },
  { <span class="hljs-attr">nombre</span>: <span class="hljs-string">'Juan'</span>, <span class="hljs-attr">edad</span>: <span class="hljs-number">22</span> },
  { <span class="hljs-attr">nombre</span>: <span class="hljs-string">'Luis'</span>, <span class="hljs-attr">edad</span>: <span class="hljs-number">17</span> },
  { <span class="hljs-attr">nombre</span>: <span class="hljs-string">'Marta'</span>, <span class="hljs-attr">edad</span>: <span class="hljs-number">25</span> }
];

<span class="hljs-keyword">const</span> mayoresDeEdad = personas.filter(<span class="hljs-function"><span class="hljs-params">persona</span> =&gt;</span> persona.edad &gt;= <span class="hljs-number">18</span>);

<span class="hljs-built_in">console</span>.log(mayoresDeEdad);
<span class="hljs-comment">// [{ nombre: 'Juan', edad: 22 }, { nombre: 'Marta', edad: 25 }]</span>
</code></pre>
<h3 id="heading-por-que-usar-filter">¿Por qué usar <code>.filter()</code>?</h3>
<ol>
<li><p><strong>Es elegante</strong>: Con una sola línea de código puedes obtener los elementos que necesitas.</p>
</li>
<li><p><strong>Es fácil de leer</strong>: Incluso si alguien más ve tu código, será fácil entender qué está haciendo.</p>
</li>
<li><p><strong>No modifica el array original</strong>: Te devuelve uno nuevo con los resultados, pero tu array original queda intacto.</p>
</li>
</ol>
<h3 id="heading-bonus-tip-filtrando-con-multiples-condiciones">Bonus Tip: Filtrando con múltiples condiciones</h3>
<p>Puedes ser aún más selectivo si lo necesitas. Por ejemplo, digamos que solo quieres las personas mayores de 18 que además se llaman "Juan" (porque eres fan de ese nombre):</p>
<pre><code class="lang-javascript">javascriptCopy codeconst juanesMayores = personas.filter(<span class="hljs-function"><span class="hljs-params">persona</span> =&gt;</span> persona.edad &gt;= <span class="hljs-number">18</span> &amp;&amp; persona.nombre === <span class="hljs-string">'Juan'</span>);

<span class="hljs-built_in">console</span>.log(juanesMayores);
<span class="hljs-comment">// [{ nombre: 'Juan', edad: 22 }]</span>
</code></pre>
<h3 id="heading-conclusion">Conclusión</h3>
<p>El método <code>.filter()</code> es súper útil y te ahorra muchas líneas de código cuando necesitas filtrar elementos de un array. Ya sea para números, strings, o incluso objetos, con <code>.filter()</code> puedes hacer que tu código sea más limpio, legible y eficiente. ¡Es como un súper poder para los arrays!</p>
]]></content:encoded></item><item><title><![CDATA[Encuentra espacios en blanco con Regex en JavaScript]]></title><description><![CDATA[En JavaScript, las expresiones regulares (regex) son una herramienta poderosa para encontrar y manipular texto. Uno de los usos más comunes es identificar espacios en blanco en cadenas de texto, ¡porque a veces esos espacios están donde menos te lo e...]]></description><link>https://kervin.blog/encuentra-espacios-en-blanco-con-regex-en-javascript</link><guid isPermaLink="true">https://kervin.blog/encuentra-espacios-en-blanco-con-regex-en-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Programación]]></category><category><![CDATA[Desarrollo Web]]></category><category><![CDATA[Regex]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Mon, 14 Oct 2024 00:39:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728867165973/bf0617f9-9317-4778-8538-082fb36ff4ea.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>En JavaScript, las expresiones regulares (regex) son una herramienta poderosa para encontrar y manipular texto. Uno de los usos más comunes es identificar espacios en blanco en cadenas de texto, ¡porque a veces esos espacios están donde menos te lo esperas! Vamos a ver cómo puedes usarlas para encontrar esos traicioneros espacios en blanco en cualquier lugar que se escondan.</p>
<h3 id="heading-que-es-un-espacio-en-blanco">¿Qué es un espacio en blanco?</h3>
<p>Primero lo primero, ¿qué cuenta como espacio en blanco? En JavaScript, los espacios en blanco no son solo los espacios normales, sino también:</p>
<ul>
<li><p>Saltos de línea (<code>\n</code>)</p>
</li>
<li><p>Tabulaciones (<code>\t</code>)</p>
</li>
<li><p>Retornos de carro (<code>\r</code>)</p>
</li>
<li><p>Espacios de diferentes tipos, como los que aparecen por un maldito "copiar y pegar" que nos vuelve locos.</p>
</li>
</ul>
<h3 id="heading-sintaxis-basica-para-encontrar-espacios-en-blanco">Sintaxis básica para encontrar espacios en blanco</h3>
<p>En regex, el patrón <code>\s</code> se utiliza para encontrar cualquier carácter de espacio en blanco. Es como el "detective" de los espacios en tu texto. Mira este ejemplo básico:</p>
<pre><code class="lang-javascript">javascriptCopy codeconst texto = <span class="hljs-string">"Hola    Mundo!"</span>;
<span class="hljs-keyword">const</span> regex = <span class="hljs-regexp">/\s/g</span>;
<span class="hljs-keyword">const</span> espacios = texto.match(regex);

<span class="hljs-built_in">console</span>.log(espacios); <span class="hljs-comment">// Output: [" ", " ", " ", " "]</span>
</code></pre>
<p>En este caso, <code>\s</code> busca cualquier espacio en blanco, y la bandera <code>g</code> asegura que busca en toda la cadena, no solo en el primer lugar donde aparece. En el ejemplo, encuentra cuatro espacios entre "Hola" y "Mundo".</p>
<h3 id="heading-como-reemplazar-o-eliminar-espacios-en-blanco">¿Cómo reemplazar o eliminar espacios en blanco?</h3>
<p>Si lo que quieres es deshacerte de esos molestos espacios o reemplazarlos, también es muy fácil con regex. Por ejemplo, podemos usar el método <code>replace</code> de JavaScript para quitar todos los espacios en blanco:</p>
<pre><code class="lang-javascript">javascriptCopy codeconst sinEspacios = texto.replace(<span class="hljs-regexp">/\s/g</span>, <span class="hljs-string">""</span>);
<span class="hljs-built_in">console</span>.log(sinEspacios); <span class="hljs-comment">// Output: "HolaMundo!"</span>
</code></pre>
<p>¡Adiós espacios! Ahora el texto está completamente "pegado".</p>
<h3 id="heading-y-si-solo-quiero-los-espacios-al-principio-o-al-final">¿Y si solo quiero los espacios al principio o al final?</h3>
<p>Para esos casos donde los espacios se acumulan al principio o al final (como después de un "copiar y pegar"), puedes usar los siguientes patrones:</p>
<ul>
<li><p><code>^\s+</code> para encontrar los espacios al <strong>inicio</strong> de la cadena.</p>
</li>
<li><p><code>\s+$</code> para encontrar los espacios al <strong>final</strong>.</p>
</li>
</ul>
<pre><code class="lang-javascript">javascriptCopy codeconst textoConEspacios = <span class="hljs-string">"   Hola Mundo!   "</span>;
<span class="hljs-keyword">const</span> sinEspaciosInicio = textoConEspacios.replace(<span class="hljs-regexp">/^\s+/</span>, <span class="hljs-string">""</span>);
<span class="hljs-keyword">const</span> sinEspaciosFinal = sinEspaciosInicio.replace(<span class="hljs-regexp">/\s+$/</span>, <span class="hljs-string">""</span>);

<span class="hljs-built_in">console</span>.log(sinEspaciosFinal); <span class="hljs-comment">// Output: "Hola Mundo!"</span>
</code></pre>
<h3 id="heading-conclusion">Conclusión</h3>
<p>Usar regex en JavaScript para encontrar espacios en blanco es súper fácil y útil. Con el patrón <code>\s</code>, puedes identificar y manipular cualquier tipo de espacio, desde el más obvio hasta el que te deja rascándote la cabeza. Ya sea que quieras eliminar espacios al principio, al final o en cualquier parte, ¡regex te tiene cubierto!</p>
]]></content:encoded></item><item><title><![CDATA[Convertir String a Array en JavaScript]]></title><description><![CDATA[JavaScript es un lenguaje muy flexible que permite convertir una cadena de caracteres en un array de una manera muy sencilla. Lo único que necesitas hacer para lograr esto es invocar el método split() sobre el string que quieres convertir. El método ...]]></description><link>https://kervin.blog/convertir-string-a-array-en-javascript</link><guid isPermaLink="true">https://kervin.blog/convertir-string-a-array-en-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[spanish]]></category><category><![CDATA[array]]></category><category><![CDATA[string]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Tue, 09 Aug 2022 05:17:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1660022170136/w609ntwq5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>JavaScript es un lenguaje muy flexible que permite convertir una cadena de caracteres en un array de una manera muy sencilla. Lo único que necesitas hacer para lograr esto es invocar el método <code>split()</code> sobre el string que quieres convertir. El método split toma como argumento el “separador” utilizado para dividir el string. Por ejemplo, si quieres obtener un array con cada uno de los caracteres lo puedes hacer la siguiente forma.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> cadena = “Hola Mundo”;
<span class="hljs-keyword">let</span> array = cadena.split(“”); <span class="hljs-comment">// =&gt; [“H”,”o”,”l”,”a”,” ”,”M”,”u”,”n”,”d”,”o”]</span>
</code></pre>
<p>Si lo que quieres es obtener un array de las palabras que conforman una cadena puedes usar el carácter espacio(<code>” ”</code>) como argumento del método <code>split()</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> cadena = “Hola Mundo”;
<span class="hljs-keyword">let</span> array = cadena.split(“ ”); <span class="hljs-comment">// =&gt; [“Hola”, “Mundo”]</span>
</code></pre>
<p>Puedes pasar otros caracteres o incluso palabras completas como argumento al método <code>split()</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> cadena = “<span class="hljs-number">123</span><span class="hljs-number">-456</span><span class="hljs-number">-789</span>”;
<span class="hljs-keyword">let</span> array = cadena.split(“-”); <span class="hljs-comment">// =&gt; [“123”,”456”,”789”]</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[¿Cómo saber si un elemento de un Array cumple una condición?]]></title><description><![CDATA[Hay situaciones en las que necesitamos saber si al menos un elemento de un array a cumple con una condición. Por ejemplo, cuando queremos saber si un array de números contiene algún número para o impar o si queremos verificar si una letra o palabra e...]]></description><link>https://kervin.blog/como-saber-si-un-elemento-de-un-array-cumple-una-condicion</link><guid isPermaLink="true">https://kervin.blog/como-saber-si-un-elemento-de-un-array-cumple-una-condicion</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[array]]></category><category><![CDATA[spanish]]></category><category><![CDATA[arreglos]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sat, 11 Jun 2022 18:19:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1654971958197/SA-21RDWQ.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hay situaciones en las que necesitamos saber si al menos un elemento de un array a cumple con una condición. Por ejemplo, cuando queremos saber si un array de números contiene algún número para o impar o si queremos verificar si una letra o palabra existe en un arreglo de strings. Esto puede ser resuelto por medio de un ciclo for y la utilización de unas cuantas variables, pero una forma aun más sencilla es por medio del método  <strong>some()</strong>.</p>
<p>Con el método <strong>some()</strong> podemos recorrer todo los elementos de un array y determinar si al menos uno de los elementos cumple con la condición deseada.</p>
<p>Digamos que tienes el siguiente arreglo:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> numeros = [<span class="hljs-number">1</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">7</span>,<span class="hljs-number">9</span>,<span class="hljs-number">0</span>];
</code></pre>
<p>Si deseamos realizar una acción solo si arreglo contiene un número par, que en este caso es el número <strong>4</strong>, podemos hacer uso del método <strong>some()</strong> de la siguiente manera:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> contieneNumeroPar = numeros.some(<span class="hljs-function"><span class="hljs-params">numero</span> =&gt;</span> numero % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>);
<span class="hljs-keyword">if</span>(contieneNumeroPar) {
<span class="hljs-built_in">console</span>.log(“El arreglo contiene un numero par”);
}
</code></pre>
<p>A como podrás imaginar, el método <strong>some()</strong> puede llegar a ser muy útil ya que te permite evaluar si alguno de los elementos del array cumple con cualquier condición que necesites verificar.</p>
]]></content:encoded></item><item><title><![CDATA[¿Cómo saber si una variable es de tipo Array en JavaScript?]]></title><description><![CDATA[Hay veces en que la función typeof no es lo suficientemente específica para saber si una variable es de tipo Array. 
Saber si una variable es de tipo Array puede llegar a ser muy útil para implementar lógica condicional más compleja dentro de una fun...]]></description><link>https://kervin.blog/como-saber-si-una-variable-es-de-tipo-array-en-javascript</link><guid isPermaLink="true">https://kervin.blog/como-saber-si-una-variable-es-de-tipo-array-en-javascript</guid><category><![CDATA[array]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[array methods]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sun, 08 Aug 2021 00:06:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1628381143821/6tXRlLkxf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hay veces en que la función <a target="_blank" href="https://kervin.blog/como-saber-el-tipo-de-una-variable-en-javascript">typeof</a> no es lo suficientemente específica para saber si una variable es de tipo Array. </p>
<p>Saber si una variable es de tipo Array puede llegar a ser muy útil para implementar lógica condicional más compleja dentro de una función.</p>
<p>Para saber si una variable es de tipo <code>Array</code>, puedes hacer uso del método estático <code>isArray()</code> que forma parte del objeto nativo de JavaScript. El método se puede utilizar de la siguiente manera:</p>
<pre><code><span class="hljs-keyword">const</span> números = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Array</span>.isArray(números)) <span class="hljs-comment">//true</span>
</code></pre><p>Este método regresara un valor booleano que puede ser evaluado en una condicional.</p>
<pre><code><span class="hljs-keyword">const</span> frutas = [“manzana”,”naranja”,”sandia”];
<span class="hljs-keyword">if</span>(<span class="hljs-keyword">Array</span>.isArray(frutas)){
   <span class="hljs-comment">//…lógica condicional</span>
}
</code></pre>]]></content:encoded></item><item><title><![CDATA[¿Cómo saber el tipo de una variable en JavaScript?]]></title><description><![CDATA[JavaScript puede llegar a ser muy flexible ya que es un lenguaje débilmente tipado. Esto significa que podemos asignarle valores de diferentes tipos a una misma variable sin ningún problema. Pero esto puede llegar a tener algunas desventajas, ya que ...]]></description><link>https://kervin.blog/como-saber-el-tipo-de-una-variable-en-javascript</link><guid isPermaLink="true">https://kervin.blog/como-saber-el-tipo-de-una-variable-en-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[array]]></category><category><![CDATA[array methods]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sat, 07 Aug 2021 23:21:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1628379998296/viK-uI22u.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>JavaScript puede llegar a ser muy flexible ya que es un lenguaje débilmente tipado. Esto significa que podemos asignarle valores de diferentes tipos a una misma variable sin ningún problema. Pero esto puede llegar a tener algunas desventajas, ya que si la lógica del código depende de que la variable sea un numero o string y por accidente asignamos un valor de tipo incorrecto a dicha variable, podemos terminar introduciendo errores de lógica en el código muy fácilmente.</p>
<p>Si la lógica de tu código depende de que una variable tenga el tipo correcto, puedes hacer uso de la palabra reservada <code>typeof</code>, la cual regresa un <code>string</code> correspondiente al tipo de la variable de la siguiente forma:</p>
<pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> <span class="hljs-number">42</span>);
<span class="hljs-regexp">//</span> salida: <span class="hljs-string">"number"</span>

<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> <span class="hljs-string">'blubber'</span>);
<span class="hljs-regexp">//</span> salida: <span class="hljs-string">"string"</span>

<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> <span class="hljs-literal">true</span>);
<span class="hljs-regexp">//</span> salida: <span class="hljs-string">"boolean"</span>

<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> variableSinDeclarar);
<span class="hljs-regexp">//</span> salida: <span class="hljs-string">"undefined"</span>
</code></pre><p>Puedes utilizar este método en una condicional para asegurarte que una variable es del tipo que esperas.</p>
<pre><code><span class="hljs-keyword">let</span> edad = <span class="hljs-number">20</span>;

<span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> edad === “<span class="hljs-built_in">number</span>”) {
    <span class="hljs-built_in">console</span>.log(“El usuario tiene ”+edad+” años”);
} <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.log(“La variable no es un numero”);
}
</code></pre>]]></content:encoded></item><item><title><![CDATA[Promesas en JavaScript]]></title><description><![CDATA[Si eres nuevo en JavaScript o quizá no has logrado comprender muy bien que son las promesas o como funcionan, espero que este articulo te ayude a entender este tema un poco más 😁.
Por naturaleza JavaScript es un lenguaje sincrono, pero una de sus pr...]]></description><link>https://kervin.blog/promesas-en-javascript</link><guid isPermaLink="true">https://kervin.blog/promesas-en-javascript</guid><category><![CDATA[promises]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[promise]]></category><category><![CDATA[functions]]></category><category><![CDATA[Functional Programming]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sun, 11 Jul 2021 23:15:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1626044900834/wWnefviea.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Si eres nuevo en JavaScript o quizá no has logrado comprender muy bien que son las promesas o como funcionan, espero que este articulo te ayude a entender este tema un poco más 😁.</p>
<p>Por naturaleza JavaScript es un lenguaje sincrono, pero una de sus principales caracteristicas es que es capaz de ejecutar código de manera asíncrona gracias a la funcionalidad de las Web API de cada navegador. Esto permite que mientras tu estes en una pagina web, multiples tareas se puedan ejecutar simultaneamente, esto hace posible que, por ejemplo, puedas ver un video en Youtube y ver los comentarios en tiempo real sin que una tarea interfiera con la otra.</p>
<p>Por mucho tiempo la manera en que se trabajaba con codigo asíncrono en JavaScript era por medio de funciones que ejecutaban el codigo dentro de ellas y que al final pasaban el resultado de esa operación a otra función conocida como "callback", que era pasada como segundo argumento a dicha función. En el siguiente ejemplo, utilizo setTimeout para simular el codigo asíncrono pero esto bien pordría ser una llamada a una API o la lectura de una base de datos.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cuadrado</span>(<span class="hljs-params">numero, callback</span>) </span>{

  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
      <span class="hljs-keyword">var</span> resultado = numero * numero;
      calback(resultado);
  },<span class="hljs-number">5000</span>);

}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cubo</span>(<span class="hljs-params">numero, callback</span>) </span>{
   <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
       <span class="hljs-keyword">var</span> resultado = numero * numero * numero;
      calback(resultado);
  },<span class="hljs-number">3000</span>);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">duplicar</span>(<span class="hljs-params">numero, callback</span>)</span>{
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        <span class="hljs-keyword">var</span> resultado = numero * <span class="hljs-number">2</span>;
      calback(resultado);
  },<span class="hljs-number">4000</span>);
}

cuadrado(<span class="hljs-number">2</span>,<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">numeroCuadrado</span>)</span>{
    cubo(numeroCuadrado,<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">numeroAlCubo</span>)</span>{
        duplicar(numeroAlCubo,<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">numeroDuplicado</span>)</span>{
            <span class="hljs-built_in">console</span>.log(numeroDuplicado);<span class="hljs-comment">//128</span>
        });
    });
});
</code></pre><p>Quiza este ejemplo no muestre la totalidad del problema ya que son operaciones sincronas, pero puedes ver como cada funcion pasa el resultado de su operación a la función callback, y al final tenemos 3 funciones anidadas. Te imaginas si necesitaras realizar aun mas operaciones. Seria muy dificil de leer y de mantener. A este problema se le ha conocido como "callback hell😈"</p>
<p>Las promesas surgen para dar una solucion a este problema y facilitar la vida de los programadores.</p>
<h2 id="promesas">Promesas</h2>
<p>Las promesas son una manera de trabajar con código asíncrono y reducir el numero de funciones callbacks.  Esta son creadas por medio de la instanciación de la clase Promise.</p>
<pre><code>    <span class="hljs-keyword">const</span> promesa = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>();
</code></pre><p>Una promesa es usualmente definidad como la representació de un valor que <strong>eventualmente</strong> estara disponible para su uso.</p>
<p>A pesar de que han existido por algun tiempo, se convirtieron en parte estandar de JavaScript en su version ES2015.</p>
<h2 id="como-funcionan-las-promesas">¿Cómo funcionan las promesas?</h2>
<p>Una vez que una promesa a sido invocada, esta entrara en estado "pendiente". Esto significa que el resto del codigo que invoco continuara la ejecución de manera normal hasta que la promesa <strong>resuelva</strong> un valor o sea <strong>rechazada</strong> debido a un error.</p>
<p>Al instanciar, o crear una nueva promesa, el constructor puede tomar dos argumentos. Los argumentos <strong>resolve</strong> y <strong>reject</strong> sirven para controlar el estado de una promesa despues de que entra en estado "pendiente".</p>
<p>El metodo <strong>resolve</strong> sirve para pasar el valor que fue resultado de la operación que ocurrio dentro de la promesa, si todo ocurrio correctamente.</p>
<p>El metodo <strong>reject</strong> sirve para pasar un valor que represente una excepción o error occurrido dentro de la promesa.</p>
<p>Utilizando promesas podemos escribir el ejemplo anterior de la siguiente manera:</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cuadrado</span>(<span class="hljs-params">numero</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>)=&gt;</span>{
          <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
              <span class="hljs-keyword">var</span> resultado = numero * numero;
              resolve(resultado);
          },<span class="hljs-number">5000</span>);
    });
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cubo</span>(<span class="hljs-params">numero</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>)=&gt;</span>{
         <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
          <span class="hljs-keyword">var</span> resultado = numero * numero * numero;
          resolve(resultado);
      },<span class="hljs-number">3000</span>);
    });
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">duplicar</span>(<span class="hljs-params">numero</span>)</span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>)=&gt;</span>{
         <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
             <span class="hljs-keyword">var</span> resultado = numero * <span class="hljs-number">2</span>;
              resolve(resultado);
          },<span class="hljs-number">4000</span>);
   }); 
}

cuadrado(<span class="hljs-number">2</span>)
.then(cubo)
.then(duplicar)
.then(<span class="hljs-function">(<span class="hljs-params">numero</span>)=&gt;</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Cualquier otra operacion con un callback"</span>);
    <span class="hljs-keyword">return</span> numero;
})
.then(<span class="hljs-built_in">console</span>.log) <span class="hljs-comment">//128</span>
</code></pre><p>A primera instancia, pareciera que el codigo se vuelve más complejo, pero si lo lees poco a poco entederas la lógica. Cada función en lugar de regresar un valor en especifico, regresa una "Promesa" de que eventualmente resolvera un valor. Al momento de invocar la primera función que regresa una promesa, podemos capturar su resultado utilizando el metodo <strong>then</strong> al cual le tenemos que pasar una funcion para utilizar el valor que la promesa resuelva. A como vez esto hace que el código sea más facil de leer.</p>
<p>Las promesas tambien nos permiten manejar excepciones o errores por medio del metodo <strong>catch</strong> este metodo es invocado cuando algo falla dentro de una promesa o cuando esta pasa a estado "rejected". Aqui te dejo un ejemplo:</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validarNumero</span>(<span class="hljs-params">valor</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>)=&gt;</span>{
        <span class="hljs-built_in">isNaN</span>(valor) ? reject(<span class="hljs-string">`<span class="hljs-subst">${valor}</span> no es un numero`</span>) : resolve(valor);
    });
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cuadrado</span>(<span class="hljs-params">numero</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>)=&gt;</span>{
          <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
              <span class="hljs-keyword">var</span> resultado = numero * numero;
              resolve(resultado);
          },<span class="hljs-number">5000</span>);
    });
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cubo</span>(<span class="hljs-params">numero</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>)=&gt;</span>{
         <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
          <span class="hljs-keyword">var</span> resultado = numero * numero * numero;
          resolve(resultado);
      },<span class="hljs-number">3000</span>);
    });
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">duplicar</span>(<span class="hljs-params">numero</span>)</span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>)=&gt;</span>{
         <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
             <span class="hljs-keyword">var</span> resultado = numero * <span class="hljs-number">2</span>;
              resolve(resultado);
          },<span class="hljs-number">4000</span>);
   }); 
}

validarNumero(<span class="hljs-number">2</span>)
.then(cuadrado)
.then(cubo)
.then(duplicar)
.then(<span class="hljs-built_in">console</span>.log) <span class="hljs-comment">//128</span>

validarNumero(<span class="hljs-string">"Hola"</span>)
.then(cuadrado)
.then(cubo)
.then(duplicar)
.then(<span class="hljs-built_in">console</span>.log)
.catch(<span class="hljs-built_in">console</span>.log)<span class="hljs-comment">// "Hola no es un numero"</span>
</code></pre><p>Cuando se genera una excepción, el resto de funciones encadenadas con el metodo <strong>then</strong> no seran ejecutadas y el codigo se saltara directamente al metodo <strong>catch</strong>.</p>
<p>Esta ejemplo te parecera un poco extraño, pero esto bien podria servir para validar si un usuario existe en una base de datos y ejectutar una acción distinta si el usuario no existe o seguir con el resto del codigo en caso de que si exista.</p>
<p>Las promesas son muy utiles para hacer tu codigo mas facil de leer y de mantener, sin contar que muchos de los modulos de JavaScript que trabajan con funciones asincronas, hacen uso de promesas. Asi que es muy importante que conoscas como funcionan.</p>
<p>Espero que hayas entendido los fundamentos de las promesas en JavaScript, pero si tienes alguna pregunta, no dudes en escribirme y seguirme en mi cuenta de  <a target="_blank" href="https://instagram.com/kervin.tech">Instagram</a> .</p>
]]></content:encoded></item><item><title><![CDATA[Obtener el tamaño de un arreglo en JavaScript]]></title><description><![CDATA[Durante tu carrera como programador te vas a encontrar muchas veces con la necesidad de conseguir el tamaño de un arreglo en JavaScript. Esto lo puedes hacer de una manera muy facil con la propiedad length.
La propiedad length regresa un número enter...]]></description><link>https://kervin.blog/obtener-el-tamano-de-un-arreglo-en-javascript</link><guid isPermaLink="true">https://kervin.blog/obtener-el-tamano-de-un-arreglo-en-javascript</guid><category><![CDATA[array]]></category><category><![CDATA[arrays]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[newbie]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sun, 11 Jul 2021 23:06:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1626044742080/GKNqmZzzn.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Durante tu carrera como programador te vas a encontrar muchas veces con la necesidad de conseguir el tamaño de un arreglo en JavaScript. Esto lo puedes hacer de una manera muy facil con la propiedad length.</p>
<p>La propiedad length regresa un número entero que representa el numero de elementos que forman parte de un arreglo.</p>
<pre><code><span class="hljs-keyword">const</span> colores = [<span class="hljs-string">"verde"</span>,<span class="hljs-string">"amarillo"</span>,<span class="hljs-string">"azul"</span>];
cosole.<span class="hljs-built_in">log</span>(colores.length); <span class="hljs-comment">//  3</span>
</code></pre><p>Esta propiedad puede resultar util de muchas formas. Como por ejemplo para obtener el ultmimo elemento de un arrego.</p>
<p>Si quires recordar como funcionan los arreglos en JavaScript puedes visitar el siguiente link:  <a target="_blank" href="/arrays-o-arreglos-en-javascript">trabajando con arrays</a> </p>
]]></content:encoded></item><item><title><![CDATA[Remover valores duplicados de un arreglo en JavaScript]]></title><description><![CDATA[Digamos que tienes un array que contiene multiples elementos de tipos primitivos como numeros o cadenas de caracteres y que algunos de estos elementos se encuentran repetidos como en el siguiente ejemplo:
const personas = ["Luis","Maria","Andres","An...]]></description><link>https://kervin.blog/remover-valores-duplicados-de-un-arreglo</link><guid isPermaLink="true">https://kervin.blog/remover-valores-duplicados-de-un-arreglo</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[array methods]]></category><category><![CDATA[arrays]]></category><category><![CDATA[array]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sun, 11 Jul 2021 23:02:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1626044315165/PsLJLoinp.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Digamos que tienes un array que contiene multiples elementos de tipos primitivos como numeros o cadenas de caracteres y que algunos de estos elementos se encuentran repetidos como en el siguiente ejemplo:</p>
<pre><code><span class="hljs-keyword">const</span> personas = [<span class="hljs-string">"Luis"</span>,<span class="hljs-string">"Maria"</span>,<span class="hljs-string">"Andres"</span>,<span class="hljs-string">"Ana"</span>,<span class="hljs-string">"Maria"</span>]; <span class="hljs-comment">//Maria esta repetida</span>
</code></pre><p>Existen diversas formas para remover los nombres duplicados y aqui primero te mostrare una forma complicada pero que puede llegar a ser muy flexible y útil.</p>
<h2 id="arrayprototypereduce">Array.prototype.reduce()</h2>
<p>El metodo reduce puede ser un poco dificil de entender al principio pero es un metodo muy poderoso.</p>
<p>Todo arreglo en JavaScript tiene acceso a este método el cual funciona muy similar al metodo <strong>map()</strong> con una distintiva diferencia. El primer argumento de este metodo es una funcion la cual a su vez recibe dos argumentos el primero conocido como el "acumulador" y sera el resultado que el metodo regresa al final de la ejecución y el segundo argumento de la funcion "callback" es el valor actual de cada elemento del arreglo dentro del ciclo.</p>
<p>El segundo argumento del método <strong>reduce()</strong> es es el valor inicial del acumulador. En nuestro caso como queremos construir un nuevo array con elementos únicos el valor inicial del método sera un arreglo vacío <strong>[ ]</strong>.</p>
<p>Para este propósito podemos utilizar este metodo para generar un array con elementos unicos de la siguiente manera:</p>
<pre><code>const personas = [<span class="hljs-string">"Luis"</span>,<span class="hljs-string">"Maria"</span>,<span class="hljs-string">"Andres"</span>,<span class="hljs-string">"Ana"</span>,<span class="hljs-string">"Maria"</span>]; //Maria esta repetida

const personasUnicas = personas.reduce(<span class="hljs-function"><span class="hljs-params">(acumulador,persona)</span>=&gt;</span>{
    <span class="hljs-keyword">return</span> !acumulador.includes(persona) ? acumulador.concat(persona) : acumulador;

},[]);

<span class="hljs-built_in">console</span>.log(personasUnicas);<span class="hljs-regexp">//</span> [<span class="hljs-string">"Luis"</span>,<span class="hljs-string">"Maria"</span>,<span class="hljs-string">"Andres"</span>,<span class="hljs-string">"Ana"</span>];
</code></pre><p>El código anterior parece más complicado de lo que es, pero si lo analizamos le encontraras la lógica.</p>
<p>Invocamos el método reduce sobre el arreglo original "personas" el método toma una función y el valor inicial de nuestro acumulador que es un array vacio donde pondremos a las personas únicas.</p>
<p>Dentro del callback en esta linea con la ayuda de un operador ternario verificamos si el nombre ya existe en el array regresamos el mismo array y no actualizamos el valor del acumulador pero si el nombre no existe en la nueva lista, regresamos una copia del acumulador y le agregamos el nombre.</p>
<pre><code><span class="hljs-comment">//........</span>
<span class="hljs-selector-tag">return</span> !<span class="hljs-selector-tag">acumulador</span><span class="hljs-selector-class">.includes</span>(persona) ? <span class="hljs-selector-tag">acumulador</span><span class="hljs-selector-class">.concat</span>(persona) : <span class="hljs-selector-tag">acumulador</span>;
<span class="hljs-comment">//.........</span>
</code></pre><p>Y al final obtendras una copia del arreglo con nombres únicos.</p>
<p>Esta forma te parecera algo complicada, pero puede llegar a ser  muy flexible ya que la puedes usar para comparar propiedades de objetos.</p>
<h2 id="clase-set">Clase Set</h2>
<p>Y ahora te muestro una manera muy facil:</p>
<pre><code><span class="hljs-keyword">const</span> personas = [<span class="hljs-string">"Luis"</span>,<span class="hljs-string">"Maria"</span>,<span class="hljs-string">"Andres"</span>,<span class="hljs-string">"Ana"</span>,<span class="hljs-string">"Maria"</span>]; <span class="hljs-comment">//Maria esta repetida</span>
<span class="hljs-keyword">const</span> personasUnicas = [...<span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(personas)];
</code></pre><p>Asi de sencillo! La clase set es un nuevo tipo de dato introducido en ES6, y se parece mucho a un array pero su principal característica es que no puede tener elementos repetidos.</p>
<p>Al inicializar set con un arreglo como parametro, este automaticamente remueve los valores duplicados. Y regresa un valor del tipo <strong>Set</strong> el cual podemos destructurar con el operador ... para crear un nuevo array con valores únicos. Este método funciona con cualquier tipo de arreglo de valores primitivos.</p>
]]></content:encoded></item><item><title><![CDATA[Insertar un elemento en una posición específica de un Array en Javascript]]></title><description><![CDATA[Digamos que necesitas insertar un nuevo elemento en un array, pero no lo quieres agregar al final, sino que lo quieres insertar en una posicion en particular. A esta posición se le llama índice.
Si necesitas un recordatorio o no estas muy familiariza...]]></description><link>https://kervin.blog/como-insertar-un-elemento-en-una-posicion-especifica-en-javascript</link><guid isPermaLink="true">https://kervin.blog/como-insertar-un-elemento-en-una-posicion-especifica-en-javascript</guid><category><![CDATA[array methods]]></category><category><![CDATA[arrays]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sun, 11 Jul 2021 22:56:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1626043808698/6FkNiyvSo.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Digamos que necesitas insertar un nuevo elemento en un array, pero no lo quieres agregar al final, sino que lo quieres insertar en una posicion en particular. A esta posición se le llama índice.</p>
<p>Si necesitas un recordatorio o no estas muy familiarizado con el funcionamiento y la sintaxis de los arreglos en JavaScript puedes visitar el siguiente enlace:  <a target="_blank" href="/arrays-o-arreglos-en-javascript">trabajando con arreglos</a>.</p>
<p>Para poder insertar un elemento en una posición específica de un array haremos uso del método splice(). Este metodo puede ser muy util, pero hay que usarlo con cuidado ya que tambien puede servir para borrar elementos.</p>
<p>El metodo splice() toma tres argumentos. El primero es el índice inicial: el lugar donde insertaremos el elemento. El segundo es el numero de elemento que quieres borrar, pero en este caso estamos añadiendo entonces pasaremos el número 0 en todos los ejemplos.</p>
<p>Digamos que tienes este array:</p>
<pre><code><span class="hljs-keyword">const</span> frutas = [<span class="hljs-string">'naranja'</span>,<span class="hljs-string">'mango'</span>];
</code></pre><p>Puedes agregar un elemento despues de "naranja" de la siguiente forma:</p>
<pre><code>frutas.splice(<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-string">'fresa'</span>);
<span class="hljs-regexp">//frutas</span> === [<span class="hljs-string">'naranja'</span>,<span class="hljs-string">'fresa'</span>,<span class="hljs-string">'mango'</span>]
</code></pre><p>Y no estamos limitados a insertar un solo elemento a la vez, sino que también puedes insertar multiples elementos de la siguiente manera:</p>
<pre><code>frutas.splice(<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-string">'fresa'</span>,<span class="hljs-string">'mandarina'</span>);
<span class="hljs-regexp">//frutas</span> === [<span class="hljs-string">'naranja'</span>,<span class="hljs-string">'fresa'</span>,<span class="hljs-string">'mandarina'</span>,<span class="hljs-string">'mango'</span>]
</code></pre><p>Para insertar un elemento en la primera posición podemos hacer lo siguiente:</p>
<pre><code>frutas.splice(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-string">'fresa'</span>);
<span class="hljs-regexp">//frutas</span> === [<span class="hljs-string">'fresa'</span>,<span class="hljs-string">'naranja'</span>,<span class="hljs-string">'mango'</span>]
</code></pre>]]></content:encoded></item><item><title><![CDATA[Convertir un Array a String en JavaScript]]></title><description><![CDATA[Para convertir un un Array o Arreglo a una cadena de caracteres, puedes hacer uso del metodo toString(). Este metodo devuelve una cadena que representa los valores del arreglo separado por comas.

Tambien podemos utilizar el metodo join() si quieres ...]]></description><link>https://kervin.blog/convertir-un-array-a-string-en-javascript</link><guid isPermaLink="true">https://kervin.blog/convertir-un-array-a-string-en-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[array methods]]></category><category><![CDATA[array]]></category><category><![CDATA[newbie]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sun, 11 Jul 2021 22:48:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1626043534390/liW5n6ruK.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Para convertir un un Array o Arreglo a una cadena de caracteres, puedes hacer uso del metodo <strong>toString()</strong>. Este metodo devuelve una cadena que representa los valores del arreglo separado por comas.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626043564346/Vx427-63s.png" alt="0ED0BE8D-97EE-49B4-AE65-ACC214930011.png" />
Tambien podemos utilizar el metodo join() si quieres usar cualquier otro caracter o cadena como separador de los elementos del array.</p>
<pre><code><span class="hljs-string">const</span> <span class="hljs-string">myArray</span> <span class="hljs-string">=</span> [<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>]<span class="hljs-string">;</span>
<span class="hljs-string">myArray.join("-");</span> <span class="hljs-string">//</span> <span class="hljs-string">"2-3-4-5-6"</span>
</code></pre>]]></content:encoded></item><item><title><![CDATA[Las 4 mejores fuentes para programar]]></title><description><![CDATA[Cuando pasas mucho tiempo escribiendo codigo en tu editor favorito, comienzas a buscar formas de personalizarlo y a la vez mejorar la experiencia luego de pasar horas y horas frente a una pantalla.
A veces, son los pequeños detalles los que hacen una...]]></description><link>https://kervin.blog/las-4-mejores-fuentes-para-programar</link><guid isPermaLink="true">https://kervin.blog/las-4-mejores-fuentes-para-programar</guid><category><![CDATA[Web Development]]></category><category><![CDATA[newbie]]></category><category><![CDATA[fonts]]></category><category><![CDATA[Text Editors]]></category><category><![CDATA[Visual Studio Code]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sun, 11 Jul 2021 22:43:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1626042744390/IiZOgTGYG.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Cuando pasas mucho tiempo escribiendo codigo en tu editor favorito, comienzas a buscar formas de personalizarlo y a la vez mejorar la experiencia luego de pasar horas y horas frente a una pantalla.</p>
<p>A veces, son los pequeños detalles los que hacen una gran diferencia. Una de las cosas que siempre me parecía un poco molesta a la hora de programar era lo dificil que es reconocer ciertas letras o encontrar ciertor errores de sintaxis debido al tipo de fuente que viene por defector en algunos editores. Es por eso que hoy te comparto 4 de las mejores fuentes para programar que haran de tu experiencia algo completamente diferente.</p>
<p>Algo que caracteriza a algunas de estas fuentes es el uso de ligaduras que permiten al combinar ciertos caracteres obtengamos una presentacion más reconocible de lo que representan.<br /><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626042777503/yDsZrtsN2.jpeg" alt="13DF92A5-64D6-470C-8C0A-2F2D514F2A0D.jpeg" /></p>
<h2 id="fira-code">Fira Code</h2>
<p>Esta ha sido una de mis fuentes favoritas por mucho tiempo y una de las mas utilizadas por programadores de todos los niveles. Esta fuente esta basada en Fira Mono de Mozilla.  Esta es la fuente que cuenta con el mayor numeros de ligaduras comparada al resto de esta lista. Definitivamente tienes que probarla.</p>
<p>Es una fuente que no es demasiado grande ni muy pequeña lo cual la hace perfecta para la mayoria de resoluciones de monitores sin necesidad tener que ajustar el tamaño en tu editor.</p>
<p>Uno de los puntos fuertes de esta fuente es su  legibilidad ya que caracteres como el número 0 y la letra O se ven completamente distintos, asi tambien como el número 1 comparado con las letra I y L.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626042859829/BwkCYjD4g.jpeg" alt="8ADAA551-B0A5-406B-84FB-C4A574F217B5.jpeg" /></p>
<p> <a target="_blank" href="https://github.com/tonsky/FiraCode?ref=kervin5">Descargar Fira Code</a></p>
<h2 id="jetbrains-mono">JetBrains Mono</h2>
<p>Absolutamente debo de contarte sobre esta fuenta ya que es mi nueva favorita y la que uso diariamente. Algo que me gusta mucho es la simpleza  del diseño pero a la vez la gran atención al detalle que le pusieron.</p>
<p>Los caracteres minúsculos tiene una altura ligeramente mayor comparados a Fira Code y esto hace que las lineas de codigo se vean de alguna manera más uniformes. Esta fuente incluye  138 ligaduras que son mas que suficientes para hacer que los operadores lógicos, aritméticos  y demás sean facilmente reconocibles. Esto te puede ahorrar valioso tiempo depurando errores de sintaxis.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626042999769/UqmE6z3eM.jpeg" alt="03660A51-DBAD-4658-995E-2F011AB533AB.jpeg" /></p>
<p> <a target="_blank" href="https://www.jetbrains.com/lp/mono/?ref=kervin.tech">Descargar JetBrains Mono</a> </p>
<h2 id="monoid">Monoid</h2>
<p>La siguiente fuente en la lista también es muy popular. Esta cuenta con un menor numero de ligaduras pero aun asi cubre los principales caracteres y expresiones de los lenguajes de programación mas populares.</p>
<p>La principal característica de esta fuente, es que es que los caracteres son relativamente más altos comparados al resto de fuentes de esta lista. Esta facilita mucho la legibilitad.</p>
<p>El diseño de esta fuente es semi-condensado lo que hace que los caracteres parezcan estar un poco mas "apretados" entre si: Lo cual puede llegar a ser util ya que ocupan menos espacio horizontal y por ende puede llegar a caber mas codigo en una sola linea. Supongo que es cuestion de gustos, puedes probarla para ver que tal te parece.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626043151880/vR-PfGyS3.jpeg" alt="C0E57591-1C8A-49D7-9FB1-328E9188BABF.jpeg" /></p>
<p> <a target="_blank" href="https://larsenwork.com/monoid/?ref=kervin.tech">Descargar Monoid</a> </p>
<h2 id="hasklig">Hasklig</h2>
<p>Esta es la ultima fuente de está lista pero no por eso significa que es mala. De hecho si te dedícas a programar en Haskell esta puede ser la fuente de tus sueños. Ya que cuenta con espacios balanceados para resaltar los glifos y representarlos más vividamente.</p>
<p>En lo que respecta al diseño de esta fuente, a pesar de ser monoespaciada tiene la apariencia de san-serif lo cual hace que se vea muy limpia en el editor.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626043278124/WMgE1bV_s.jpeg" alt="70AED5DF-9A4C-4AD6-8765-96CA635E0DA8.jpeg" /></p>
<p> <a target="_blank" href="https://github.com/i-tu/Hasklig?ref=kervin.tech">Descargar Hasklig</a></p>
<p>Estas son algunas de mis fuentes favoritas. Pruebalas a vel cual te gusta más y si tienes alguna otra que te gustaria que otros conozcan, escribeme a contact@kervin.tech😎 para agregarla a la lista. </p>
]]></content:encoded></item><item><title><![CDATA[Obtener el ultimo elemento de un arreglo en JavaScript]]></title><description><![CDATA[Quiza te has encontrado con la necesidad de obtener el ultimo elemento de un array o arreglo en JavaScript. Por lo menos a mi me ha pasado y me di cuenta que unas de las maneras más faciles de lograrlo sin modificar el array original es haciendo uso ...]]></description><link>https://kervin.blog/obtener-el-ultimo-elemento-de-un-array-en-javascript</link><guid isPermaLink="true">https://kervin.blog/obtener-el-ultimo-elemento-de-un-array-en-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[newbie]]></category><category><![CDATA[array methods]]></category><category><![CDATA[arrays]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sun, 11 Jul 2021 22:27:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1626042394657/OSApRMqMxD.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Quiza te has encontrado con la necesidad de obtener el ultimo elemento de un array o arreglo en JavaScript. Por lo menos a mi me ha pasado y me di cuenta que unas de las maneras más faciles de lograrlo sin modificar el array original es haciendo uso de la propiedad length.</p>
<p>Supongamos que tenemos el siguiente arreglo:</p>
<pre><code><span class="hljs-keyword">const</span> nombres = [<span class="hljs-string">"Juan"</span>,<span class="hljs-string">"Maria"</span>,<span class="hljs-string">"Yolanda"</span>,<span class="hljs-string">"Roberto"</span>];
</code></pre><p>Sabemos que podemos acceder a cada elemento del array nombres por medio de su indice. Es decir que el primer nombre se puede obtener con <strong>nombres[0]</strong>, el segundo con <strong>nombres[1]</strong> y asi sucesivamente. Si no sabias esto puedes darte una vuelta en el articulo sobre como trabajar con arreglos.</p>
<p>Entonces, para obtener el ultimo elemento solo necesitas saber cual es su indice el cual se puede calcular facilmente al saber el tamaño del arreglo por medio de la propiedad length. Usando esa propiedad podemos aplicar la siguiente formular <strong>.length - 1</strong>.</p>
<p>Y asi lograremos acceder al ultimo elemento del arreglo.</p>
<pre><code><span class="hljs-keyword">const</span> ultimoElemento = nombres[nombres.length - <span class="hljs-number">1</span>]
</code></pre>]]></content:encoded></item><item><title><![CDATA[Sustituir los espacios en blanco de una cadena de caracteres en JavaScript 🔥]]></title><description><![CDATA[Esta es una de las tareas más comunes en cualquier lenguaje de programación.
Por ejemplo en el caso de un usuario que sube una image llamada "Mi nueva foto.jpg", y por motivos de funcionalidad es necesario guardarla en el servidor con el nombre "Mi-n...]]></description><link>https://kervin.blog/sustituir-los-espacios-en-blanco-de-una-cadena-de-caracteres-en-javascript</link><guid isPermaLink="true">https://kervin.blog/sustituir-los-espacios-en-blanco-de-una-cadena-de-caracteres-en-javascript</guid><category><![CDATA[array]]></category><category><![CDATA[array methods]]></category><category><![CDATA[string]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[newbie]]></category><dc:creator><![CDATA[Kervin Vasquez]]></dc:creator><pubDate>Sun, 11 Jul 2021 22:22:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1626042124833/Ud1L9U8U1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Esta es una de las tareas más comunes en cualquier lenguaje de programación.</p>
<p>Por ejemplo en el caso de un usuario que sube una image llamada "Mi nueva foto.jpg", y por motivos de funcionalidad es necesario guardarla en el servidor con el nombre "Mi-nueva-foto.jpg".</p>
<p>Para sustituir los espacios en blanco por cualquier otro caracter, o inclusive para remover los espacios en blanco, podemos hacer uso de  <a target="_blank" href="https://es.wikipedia.org/wiki/Expresi%C3%B3n_regular">expresiones regulares</a> .</p>
<p>Aqui un ejemplo:</p>
<pre><code><span class="hljs-keyword">const</span> nombreImagen = <span class="hljs-string">'Mi nueva foto.jpg'</span>
nombreImage.replace(<span class="hljs-regexp">/\s/g</span>, <span class="hljs-string">''</span>) <span class="hljs-comment">//Mi-nueva-foto.jpg</span>
</code></pre><p>El meta caracter \s sirve para encontrar cualquier espacio en blanco por medio de una expresion regular. Y la bandera g le dice a JavaScript no solo actuar sobre el primer caracter que encuentre sino todos los que existan en la cadena de caracteres.</p>
<p>El valor de la variable original no cambia. Entonces, si quieres usar el nuevo valor en alguna otra parte de tu codigo, debes almacenarlo en otra variable.</p>
<pre><code><span class="hljs-keyword">const</span> nombreImagen = <span class="hljs-string">'Mi nueva foto.jpg'</span>
<span class="hljs-keyword">const</span> nuevoNombreImage = nombreImagen.replace(<span class="hljs-regexp">/\s/g</span>, <span class="hljs-string">''</span>) <span class="hljs-comment">//Mi-nueva-foto.jpg</span>
</code></pre>]]></content:encoded></item></channel></rss>