<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ BlackeyeB - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Descubre miles de cursos de programación escritos por expertos. Aprende Desarrollo Web, Ciencia de Datos, DevOps, Seguridad y obtén asesoramiento profesional para desarrolladores. ]]>
        </description>
        <link>https://www.freecodecamp.org/espanol/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ BlackeyeB - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/espanol/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 15 May 2026 04:13:37 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/espanol/news/author/blackeyeb/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ ¿Qué es el modelo de objetos del documento (DOM) y por qué deberías saber cómo usarlo? ]]>
                </title>
                <description>
                    <![CDATA[ Si has estudiado HTML, creaste tus primeras etiquetas, aprendiste sobre CSS, creaste hermosos formularios, botones increíbles, páginas receptivas y comenzaste a mostrarles a todos lo increíble que era todo eso. Y ahora decides que quieres dar un paso más en tu aprendizaje y empiezas a preguntarte: “¿Cómo puedo agregar animación ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/que-es-el-modelo-de-objetos-del-documento-y-por-que-debes-saber-como-usarlo/</link>
                <guid isPermaLink="false">644f5e9de59d8f07c2db3506</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Thu, 11 May 2023 00:53:55 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/05/1_q8vHD5jcU_xZNqIgs-J-Pg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/whats-the-document-object-model-and-why-you-should-know-how-to-use-it-1a2d0bc5429d/#:~:text=Advantages,the%20page%20without%20a%20refresh" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">What’s the Document Object Model, and why you should know how to use it.</a>
      </p><p>Si has estudiado HTML, creaste tus primeras etiquetas, aprendiste sobre CSS, creaste hermosos formularios, botones increíbles, páginas receptivas y comenzaste a mostrarles a todos lo increíble que era todo eso.</p><p>Y ahora decides que quieres dar un paso más en tu aprendizaje y empiezas a preguntarte: “¿Cómo puedo agregar animación a mi página? ¡Ojalá ese botón hiciera alguna animación en mi página cuando haces clic en él!”</p><p>Bueno, ahí es donde viene el DOM para resolver tu problema. Probablemente, hayas escuchado mucho al respecto, pero es posible que aún no sepas qué es y qué problemas resuelve. Así que profundicemos.</p><h3 id="entonces-qu-es-el-dom"><strong>Entonces, ¿qué es el DOM?</strong></h3><p>¿Conoces todas esas animaciones geniales que ves a tu alrededor, que te hacen pensar: "Vaya, me gustaría poder hacer algo así"? Todas esas animaciones se realizan manipulando el DOM. Ahora te explicaré cómo comenzar a manipularlo y hacer que tus sitios web se vean geniales.</p><p>El DOM (Modelo de Objetos del Documento, por sus siglas en inglés: Document Object Model) es una interfaz que representa cómo el navegador lee tus documentos HTML y XML. Permite que un lenguaje (JavaScript) manipule, estructure y estilice tu sitio web. Una vez que el navegador lee tu documento HTML, crea un árbol de representación llamado Modelo de Objetos del Documento y define cómo se puede acceder a ese árbol.</p><h3 id="ventajas"><strong>Ventajas</strong></h3><p>Manipulando el DOM, tienes infinitas posibilidades. Puedes crear aplicaciones que actualicen los datos de la página sin necesidad de actualizar. Además, puedes crear aplicaciones personalizables por el usuario y luego cambiar el diseño de la página sin actualizar. Puedes arrastrar, mover y eliminar elementos.</p><p>Como dije, tienes infinitas posibilidades, solo necesitas usar tu creatividad.</p><h3 id="representaci-n-por-el-navegador"><strong>Representación por el navegador</strong></h3><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-media-1.freecodecamp.org/images/3n6SPcMH0mmG6cFeB3SJBEA-9Yyfgp3xYZ7u" class="kg-image" alt="3n6SPcMH0mmG6cFeB3SJBEA-9Yyfgp3xYZ7u" width="800" height="666" loading="lazy"><figcaption>El árbol de representación que crea el navegador tras leer tu documento.</figcaption></figure><p>En la imagen de arriba, podemos ver el árbol de representación y cómo lo crea el navegador. En este ejemplo, tenemos cuatro elementos importantes que verás mucho:</p><ol><li><strong>Documento</strong>: Trata todos los documentos <em><em>HTML</em></em>.</li><li><strong>Elementos</strong>: Todas las etiquetas que están dentro de tu <em><em>HTML</em></em> o <em><em>XML</em></em> se convierten en un elemento DOM.</li><li><strong>Texto</strong>: Todo el contenido de las etiquetas.</li><li><strong>Atributos</strong>: Todos los atributos de un elemento <em><em>HTML</em></em> específico. En la imagen, el atributo <em><em>class=”hero”</em></em> es un atributo del elemento <em><em>&lt;</em></em> p&gt;.</li></ol><h3 id="manipulando-el-dom"><strong>Manipulando el DOM</strong></h3><p>Ahora estamos llegando a la mejor parte: Comenzar a manipular el DOM. Primero, vamos a crear un elemento HTML como ejemplo para ver algunos métodos y cómo funcionan los eventos.</p><pre><code>&lt;!DOCTYPE html&gt;  &lt;html lang="pt-br"&gt;  &lt;head&gt;      &lt;meta charset="UTF-8"&gt;      &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;      &lt;meta http-equiv="X-UA-Compatible" content="ie=edge"&gt;      &lt;title&gt;Entendiendo el DOM (Document Object Model)&lt;/title&gt;  &lt;/head&gt;  &lt;body&gt;      &lt;div class="container"&gt;          &lt;h1&gt;&lt;time&gt;00:00:00&lt;/time&gt;&lt;/h1&gt;          &lt;button id="start"&gt;Start&lt;/button&gt;          &lt;button id="stop"&gt;Stop&lt;/button&gt;          &lt;button id="reset"&gt;Reset&lt;/button&gt;      &lt;/div&gt;  &lt;/body&gt;  &lt;/html&gt;</code></pre><p>Muy sencillo, ¿verdad? Ahora vamos a aprender más sobre los métodos DOM: cómo obtener nuestros elementos y comenzar a manipularlos.</p><h3 id="m-todos"><strong>Métodos</strong></h3><p>El DOM tiene muchos métodos. Son la conexión entre nuestros nodos (elementos) y eventos, algo de lo que aprenderemos más adelante. Te mostraré algunos de los métodos más importantes y cómo se usan. Hay muchos más métodos que no voy a mostrarte aquí, pero puedes verlos todos <a href="https://developer.mozilla.org/es/docs/Web/API/Document_Object_Model/Introduction">aquí</a>.</p><h4 id="getelementbyid-"><strong><strong>getElementById()</strong></strong></h4><p>Este método devuelve el elemento que contiene el <em><em>ID</em></em> de nombre pasado. Como sabemos, <em><em>las identificaciones</em></em> deben ser únicas, por lo que es un método muy útil para obtener solo el elemento que desea.</p><pre><code>var myStart = document.getElementsById('start');</code></pre><p><strong><strong>myStart</strong></strong> : Nuestro nombre de variable que se parece a nuestra <em><em>identificación</em></em> pasada.</p><p><strong>start</strong> : <em><em>id</em></em> pasado. Y en caso de que no tengamos ningún <em><em>id</em></em> con ese nombre en concreto, devuelve <em><em>nulo</em></em>.</p><h4 id="getelementsbyclassname-"><strong><strong>getElementsByClassName()</strong></strong></h4><p>Este método devuelve una colección <em><em>HTML</em></em> de todos los elementos que contienen la <em><em>clase</em></em> de nombre específico pasado.</p><pre><code>var myContainer = document.getElementsByClassName('container');</code></pre><p><strong><strong>myContainer</strong></strong>: Nuestro nombre de variable que se parece a nuestra <em><em>clase</em></em> pasada.</p><p><strong><strong>.container</strong></strong>: Nuestra <em><em>clase</em></em> pasada. En caso de que no tengamos ninguna <em><em>clase</em></em> con ese nombre en concreto, devuelve <em><em>nulo</em></em>.</p><h4 id="getelementsbytagname-"><strong><strong>getElementsByTagName()</strong></strong></h4><p>Esto funciona de la misma manera que los métodos anteriores: También devuelve una colección <em><em>HTML,</em></em> pero esta vez con una sola diferencia: Devuelve todos esos <em><em>elementos</em></em> con el nombre de la etiqueta pasado.</p><pre><code>var buttons = document.getElementsByTagName('button');</code></pre><p><strong><strong>b</strong>uttons</strong>: Nuestro nombre de variable que se parece a nuestro <em><em>nombre de etiqueta</em></em> pasado.</p><p><strong><strong>button</strong></strong>: <em><em>nombre de la etiqueta</em></em> que queremos obtener.</p><h4 id="queryselector-"><strong><strong>querySelector()</strong></strong></h4><p>Devuelve el primer <em><em>elemento</em></em> que tiene el <em><em>selector CSS </em></em>específico<em> </em>pasado<em><em>. </em></em>Solo recuerda que el <em><em>selector</em></em> debe seguir la <em><em>sintaxis CSS</em></em>. En caso de no tener ningún <em><em>selector</em></em> , devuelve <em><em>nulo</em></em>.</p><pre><code>var resetButton = document.querySelector('#reset');</code></pre><p><strong><strong>resetButton</strong></strong>: Nuestro nombre de variable que se parece a nuestro <em><em>selector</em></em> pasado.</p><p><strong><strong>#reset</strong></strong>: <em><em>el selector</em></em> pasado, y si no tiene ningún <em><em>selector</em></em> que coincida, devuelve <em><em>nulo</em></em>.</p><h4 id="queryselectorall-"><strong><strong>querySelectorAll()</strong></strong></h4><p>Muy similar al método <em><em>querySelector()</em></em>, pero con una única diferencia: devuelve todos los <em><em>elementos</em></em> que coinciden con el <em><em>selector CSS</em></em> pasado. El <em><em>selector</em></em> también debe seguir la <em><em>sintaxis CSS</em></em>. En caso de no tener ningún <em><em>selector</em></em>, devuelve <em><em>nulo</em></em>.</p><pre><code>var myButtons = document.querySelector('#buttons');</code></pre><p><strong><strong>myButtons</strong></strong>: Nuestro nombre de variable que se parece a nuestro <em><em>selector</em></em> pasados.</p><p><strong><strong>#botones</strong></strong>: <em><em>selector</em></em> pasado, si no tiene ningún <em><em>selector</em></em> que coincida, devuelve <em><em>nulo</em></em>.</p><p>Estos son algunos de los métodos DOM más utilizados. Hay varios métodos más que puedes usar, como createElement(), que crea un nuevo elemento en tu página HTML, y setAttribute() que te permite establecer nuevos atributos para elementos HTML. Puedes explorarlos por tu cuenta.</p><p>Nuevamente, puedes encontrar todos los métodos <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element" rel="noopener">aquí</a>, en el lado izquierdo, en <em><em>Métodos</em></em> . Realmente te recomiendo que eches un vistazo a algunos de los otros porque es posible que pronto necesites alguno de ellos.</p><p>Ahora, vamos a aprender acerca de <strong><strong>los eventos</strong></strong>; después de todo, sin ellos no podemos hacer animaciones en nuestras páginas.</p><h3 id="eventos"><strong>Eventos</strong></h3><p>Los elementos DOM tienen <em><em>métodos</em></em>, como acabamos de comentar, pero también tienen <em><em>eventos</em></em>. Estos eventos son los encargados de hacer posible la interactividad en nuestra página. Pero aquí hay una cosa que quizás no sepas: <em><em>los eventos</em></em> también son <em><em>métodos</em></em>.</p><pre><code>myStart.addEventListener('click', function(event) {</code></pre><h4 id="click"><strong>C<strong>lick</strong></strong></h4><p>Uno de los eventos más utilizados es el evento click. Cuando el usuario hace clic en un elemento específico, realizará alguna acción.</p><pre><code>// Haz algo aquí.</code></pre><pre><code>}, false);</code></pre><p>Los parámetros de addEventListener() son:</p><ol><li>El tipo de evento que quieras (en este caso ' <em><em>clic</em>k</em> ').</li><li>Una función callback (de devolución de llamada)</li><li>El <em><em>useCapture</em></em> por defecto es falso. Indica si quieres o no “capturar” el evento.</li></ol><h4 id="select"><strong><strong>select</strong></strong></h4><p>Este evento es para cuando quieres <em><em>enviar</em></em> (dispatch) algo cuando se selecciona un elemento específico. <em><em>En ese caso , enviaremos</em></em> una <em><em>alerta</em></em> simple .</p><pre><code>myStart.addEventListener('select', function(event) {</code></pre><pre><code>alert('Element selected!');</code></pre><pre><code>}, false);</code></pre><p>Estos son algunos de los eventos más utilizados. Por supuesto, tenemos muchos otros eventos que puedes usar, como eventos de arrastrar y soltar: cuando un usuario comienza a arrastrar algún elemento, puede realizar alguna acción, y cuando suelta ese elemento, puedes realizar otra acción.</p><p>Ahora, veremos cómo podemos recorrer el DOM y usar algunas propiedades.</p><h3 id="recorriendo-el-dom"><strong>Recorriendo el DOM</strong></h3><p>Puedes recorrer el DOM y usar algunas propiedades que veremos ahora. Con estas propiedades, puedes devolver elementos, comentarios, texto, etc.<br></p><h4 id="-childnodes"><strong><strong>.childNodes</strong></strong></h4><p>Esta propiedad devuelve una <em><em>lista de nodos</em></em> secundarios del elemento dado. Devuelve texto, comentarios, etc. Cuando quieras usarlo, debes tener cuidado.</p><pre><code>var container = document.querySelector('.container');</code></pre><pre><code>var getContainerChilds = container.childNodes;</code></pre><h4 id="-firstchild"><strong><strong>.firstChild</strong></strong></h4><p>Esta propiedad devuelve el primer hijo del elemento dado.</p><pre><code>var container = document.querySelector('.container');</code></pre><pre><code>var getFirstChild = container.firstChild;</code></pre><h4 id="-nodename"><strong><strong>.nodeName</strong></strong></h4><p>Esta propiedad devuelve el nombre del elemento dado. En este caso, pasamos un <em><em>div</em></em> , por lo que devolverá " <em><em>div</em></em> ".</p><pre><code>var container = document.querySelector('.container');</code></pre><pre><code>var getName = container.nodeName;</code></pre><h4 id="-nodevalue"><strong><strong>.nodeValue</strong></strong></h4><p>Esta propiedad es específica para <strong><strong>textos y comentarios</strong></strong> , ya que devuelve o establece el valor del <em><em>nodo</em></em> actual . En este caso, dado que pasamos un div, devolverá <em><em>nulo</em></em> .</p><pre><code>var container = document.querySelector('.container')</code></pre><pre><code>var getValue = container.nodeValue;</code></pre><h4 id="-nodetype"><strong><strong>.nodeType</strong></strong></h4><p>Esta propiedad devuelve el <strong><strong>tipo</strong></strong> del elemento dado. En este caso, devuelve “ <em><em>1</em></em> ”.</p><pre><code>var container = document.querySelector('.container')</code></pre><pre><code>var getValue = container.nodeType;</code></pre><p>Pero, ¿qué significa " <em><em>1</em></em> " de todos modos? Es básicamente el <strong><strong>tipo de nodo</strong></strong> del elemento dado. En este caso, es un <em><em>_ELEMENT_NODE_</em></em> y devuelve nulo. Si esto fuera un atributo, nos sería devuelto como " <em><em>2 " y el valor del atributo.</em></em></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-media-1.freecodecamp.org/images/YOtuBjNlEsuJckztC-v5YHKvTJx2PNQBQQ23" class="kg-image" alt="YOtuBjNlEsuJckztC-v5YHKvTJx2PNQBQQ23" width="800" height="309" loading="lazy"><figcaption>Una tabla que contiene todos los tipos de nodeTypes y el nodeName y nodeValue devueltos por cada uno de ellos.</figcaption></figure><p>Puede leer más sobre <em><em>los tipos de nodos </em></em><a href="https://www.w3schools.com/jsref/prop_node_nodetype.asp" rel="noopener">aquí</a>.</p><h3 id="elements"><strong><strong>Elements</strong></strong></h3><p>Estas propiedades, en lugar de las anteriores, nos devuelven solo <strong><strong>elementos</strong></strong>. Se usan y recomiendan con más frecuencia porque pueden causar menos confusión y son más fáciles de entender.</p><h4 id="-parentnode"><strong><strong>.parentNode</strong></strong></h4><p>Esta propiedad devuelve el padre del nodo dado.</p><pre><code>var container = document.querySelector('.container')</code></pre><pre><code>var getParent = container.parentNode;</code></pre><h4 id="-firstelementchild"><strong><strong>.firstElementChild</strong></strong></h4><p>Devuelve el primer elemento secundario del elemento dado.</p><pre><code>var container = document.querySelector('.container')</code></pre><pre><code>var getValue = container.firstElementChild;</code></pre><h4 id="-lastelementchild"><strong><strong>.lastElementChild</strong></strong></h4><p>Devuelve el último elemento secundario del elemento dado.</p><pre><code>var container = document.querySelector('.container')</code></pre><pre><code>var getValue = container.lastElementChild;</code></pre><p>Estas son algunas de las muchas propiedades que tiene el DOM. Es muy importante que conozcas los conceptos básicos sobre el DOM, cómo funciona, sus métodos y propiedades, porque algún día puedes necesitarlo.</p><h3 id="conclusi-n"><strong>Conclusión</strong></h3><p>El DOM nos proporciona varias API importantes para crear aplicaciones fantásticas e innovadoras. Si entiendes los conceptos básicos, puedes crear cosas increíbles. Si deseas leer más sobre el DOM, puedes hacer clic <a href="https://developer.mozilla.org/en-US/docs/Glossary/DOM" rel="noopener">aquí</a> y leer todos los documentos de MDN.</p><p>¡<a href="https://twitter.com/leonardomso" rel="noopener"><strong><strong>Sígueme en Twitter!</strong></strong></a><br><strong><strong>⭐</strong></strong> ¡ <a href="https://github.com/leonardomso" rel="noopener"><strong><strong>Sígueme en GitHub!</strong></strong></a></p><p><em><em>Estoy buscando una oportunidad remota, si </em>puedes darme<em> alguna, me encantaría saber sobre ella, ¡así que contáct</em>a<em>me!</em></em></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Constructores en Dart: Casos de uso y ejemplos ]]>
                </title>
                <description>
                    <![CDATA[ La mayoría de nosotros estamos familiarizados con el concepto de constructores. Nos permiten crear diferentes instancias de nuestras clases. Podemos especificar de qué parámetros debe depender la clase cuando se crea una instancia y ocultar la lógica de inicialización interna. Podemos tener muchos constructores para diferentes casos de uso, o ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/constructores-en-dart-casos-de-uso-y-ejemplos/</link>
                <guid isPermaLink="false">644a3512db9a5007c084a721</guid>
                
                    <category>
                        <![CDATA[ dart ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Fri, 05 May 2023 00:59:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/04/60591ab5687d62084bf6a7c6.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/constructors-in-dart/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Constructors in Dart – Use Cases and Examples</a>
      </p><p>La mayoría de nosotros estamos familiarizados con el concepto de constructores. Nos permiten crear diferentes instancias de nuestras clases. Podemos especificar de qué parámetros debe depender la clase cuando se crea una instancia y ocultar la lógica de inicialización interna.</p><p>Podemos tener muchos constructores para diferentes casos de uso, o podemos confiar en el predeterminado.</p><p>En dart, los constructores juegan un papel similar, pero tienen algunas variaciones que no existen en la mayoría de los lenguajes de programación. Este artículo repasa los diferentes casos de uso y ejemplos de constructores.</p><p>En todos los ejemplos de este artículo, usaremos la siguiente clase:</p><pre><code class="language-dart">class Coche {
   String fabricacion;
   String modelo;
   String anyoFabricacion;
   bool tieneABS;
}</code></pre><h2 id="c-mo-empezar-con-los-constructores-en-dart"><strong>Cómo empezar con los constructores en Dart</strong></h2><p>Si no especificas ningún constructor en Dart, crearás un constructor predeterminado.</p><p>Esto no significa que verás un constructor predeterminado generado en su clase. En cambio, al crear una nueva instancia de tu clase, se llamará a este constructor. No tendrá argumentos y llamará al constructor de la superclase, sin argumentos también.</p><p>Para declarar un constructor en tu clase, puedes hacer lo siguiente:</p><pre><code class="language-dart">class Coche {
	String fabricacion;
   	String modelo;
   	String anyoFabricacion;
   	bool tieneABS;
   
   	Coche(String fabricacion, String modelo, int anyo, bool tieneABS) {
    	this.fabricacion = fabricacion;
      	this.modelo = modelo;
      	this.anyoFabricacion = anyo;
      	this.tieneABS = tieneABS;
   	}
}</code></pre><p>Como puedes imaginar, debe haber una mejor manera de inicializar nuestros campos de clase, y en Dart, la hay:</p><pre><code class="language-dart">class Coche {
	String fabricacion;
   	String modelo;
   	String anyoFabricacion;
   	bool tieneABS;
   
   	Coche(this.fabricacion, this.modelo, this.anyoFabricacion, this.tieneABS);
}</code></pre><p>La forma que usamos arriba es una sintaxis sencilla que Dart tiene para simplificar la asignación.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-321.png" class="kg-image" alt="image-321" width="600" height="400" loading="lazy"><figcaption>Photo by <a href="https://unsplash.com/@lin_alessio?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Alessio Lin</a> / <a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Unsplash</a></figcaption></figure><h2 id="funciones-de-constructor-m-s-complejas">F<strong>unciones de constructor más complejas</strong></h2><p>En otros idiomas, es posible sobrecargar tu constructor. Esto significa que puedes tener diferentes constructores con el mismo nombre, pero con una firma diferente (o un conjunto diferente de argumentos).</p><h3 id="constructores-con-nombre-en-dart"><strong>Constructores con nombre en Dart</strong></h3><p>En Dart, esto no es posible, pero hay una forma de hacer algo semejante. Se llama <strong><strong>constructores </strong>con nombre</strong>. Dar a tus constructores diferentes nombres le permite a tu clase tener muchos constructores y también representar mejor sus casos de uso fuera de la clase.</p><figure class="kg-card kg-code-card"><pre><code class="language-dart">class Coche {
	String fabricacion;
   	String modelo;
   	String anyoFabricacion;
   	bool tieneABS;
   
   	Coche(this.fabricacion, this.modelo, this.anyoFabricacion, this.tieneABS);
   
   	Coche.sinABS(this.fabricacion, this.modelo, this.anyoFabricacion): tieneABS = false;
}</code></pre><figcaption>Ejemplo de constructor con nombre</figcaption></figure><p>El constructor <strong><strong>sinABS</strong></strong> inicializa la variable de instancia tieneABS en falso, antes de que se ejecute el cuerpo del constructor. Esto se conoce como <strong><strong>lista de inicializadores</strong></strong> y puede inicializar varias variables, separadas por una coma.</p><p>El caso de uso más común para las listas de inicializadores es inicializar los campos finales declarados por tu clase.</p><blockquote>✋ Cualquier cosa que se coloque en el lado derecho de los dos puntos (:) no tiene acceso a <strong>this</strong>.</blockquote><h3 id="constructores-de-factor-as-en-dart"><strong>Constructores de Factorías en Dart</strong></h3><p>Un constructor de factoría es un constructor que se puede usar cuando no necesariamente deseas que un constructor cree una nueva instancia de tu clase.</p><p>Esto podría ser útil si tienes instancias de tu clase en la memoria y no deseas crear una nueva cada vez (o si la operación de crear una instancia es costosa).</p><p>Otro caso de uso es si tienes cierta lógica en tu constructor para inicializar un campo final que no se puede hacer en la lista de inicializadores.</p><figure class="kg-card kg-code-card"><pre><code class="language-dart">class Coche {
	String fabricacion;
   	String modelo;
   	String anyoFabricacion;
   	bool tieneABS;
   
   	factory Coche.ford(String modelo, String anyoFabricacion, bool tieneABS) {
    	return CocheFord(modelo, anyoFabricacion, tieneABS);
    }
}

class CocheFord extends Coche {
	CocheFord(String modelo, String anyoFabricacion, bool tieneABS): super("Ford", modelo, anyoFabricacion, tieneABS);
 
}</code></pre><figcaption>Ejemplo de constructor de factoría</figcaption></figure><h2 id="constructores-avanzados-en-dart"><strong>Constructores avanzados en Dart</strong></h2><h3 id="constructores-de-constantes-y-constructores-de-redireccionamiento-en-dart"><strong>Constructores de constantes y constructores de redireccionamiento en Dart</strong></h3><p>Dart también te permite crear constructores de constantes. ¿Qué significa exactamente? Si tu clase representa un objeto que nunca cambiará después de su creación, puede beneficiarse del uso de un constructor de constante. Debes asegurarte de que todos los campos de tu clase sean definitivos.</p><figure class="kg-card kg-code-card"><pre><code class="language-dart">class FordFocus {
   static const FordFocus fordFocus = FordFocus("Ford", "Focus", "2013", true);
   
   final String fabricacion;
   final String modelo;
   final String anyoFabricacion;
   final bool tieneABS;
   
   const FordFocus(this.fabricacion, this.modelo, this.anyoFabricaion, this.tieneABS);
   
}</code></pre><figcaption>Ejemplo de constructor de constante</figcaption></figure><p>Cuando deseas que un constructor llame a otro constructor en segundo plano, se le denomina <strong><strong>constructores de redireccionamiento</strong></strong>.</p><figure class="kg-card kg-code-card"><pre><code class="language-dart">class Coche {
	String fabricacion;
   	String modelo;
   	String anyoFabricacion;
   	bool tieneABS;
   
   	Coche(this.fabricacion, this.modelo, this.anyoFabricacion, this.tieneABS);
   
   	Coche.sinABS(this.fabricacion, this.modelo, this.anyoFabricacion): this(fabricacion, modelo, anyoFabricacion, false);
}</code></pre><figcaption>Ejemplo de constructor de redirección</figcaption></figure><h2 id="para-acabar">Para acabar</h2><p>Cada uno de los constructores que discutimos tiene un propósito y un caso de uso diferente. Depende de ti determinar y comprender cuándo usar cada uno. Con suerte, este artículo te dio el conocimiento necesario para hacerlo.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Qué es Flutter y por qué deberías aprenderlo en 2020 ]]>
                </title>
                <description>
                    <![CDATA[ Este año, las aplicaciones móviles continúan siendo cada vez más populares. Por suerte hay muchas herramientas de programación disponibles para los desarrolladores que quieran crearlas. Entre estas herramientas está Flutter, que se ha destacado últimamente. ¿Qué es Flutter? Flutter es un framework de interfaz de usuario móvil gratuito y de ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/que-es-flutter-y-porque-deberias-aprenderlo-en-2020/</link>
                <guid isPermaLink="false">64498a44db9a5007c084a268</guid>
                
                    <category>
                        <![CDATA[ flutter ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Mon, 01 May 2023 13:43:44 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/04/what-is-flutter-and-why-you-should-learn-it-in-2020---copia.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/what-is-flutter-and-why-you-should-learn-it-in-2020/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">What is Flutter and Why You Should Learn it in 2020</a>
      </p><p>Este año, las aplicaciones móviles continúan siendo cada vez más populares. Por suerte hay muchas herramientas de programación disponibles para los desarrolladores que quieran crearlas. Entre estas herramientas está Flutter, que se ha destacado últimamente.</p><h2 id="-qu-es-flutter"><strong>¿Qué es Flutter?</strong></h2><p>Flutter es un framework de interfaz de usuario móvil gratuito y de código abierto creado por Google y lanzado en mayo de 2017. En pocas palabras, te permite crear una aplicación móvil nativa con una sola base de código. Esto significa que puedes usar un lenguaje de programación y una base de código para crear dos aplicaciones diferentes (para iOS y Android).</p><p>Flutter consta de dos partes importantes:</p><ul><li>Un SDK (Software Development Kit): Una colección de herramientas que te ayudarán a desarrollar tus aplicaciones. Esto incluye herramientas para compilar tu código en código de máquina nativo (código para iOS y Android).</li><li>Un framework (biblioteca de interfaz de usuario basada en widgets): Una colección de elementos de interfaz de usuario reutilizables (botones, entradas de texto, controles deslizantes, etc.) que puedes personalizar según tus propias necesidades.</li></ul><p>Para desarrollar con Flutter, utilizarás un lenguaje de programación llamado Dart. El lenguaje fue creado por Google en octubre de 2011, pero ha mejorado mucho en los últimos años.</p><p>Dart se enfoca en el desarrollo front-end y puedes usarlo para crear aplicaciones móviles y web.</p><p>Si sabes un poco de programación, Dart es un lenguaje de programación de objetos escritos. Puedes comparar la sintaxis de Dart con JavaScript.</p><blockquote>"Flutter es el conjunto de herramientas de interfaz de usuario de Google para crear bonitas aplicaciones compiladas de forma nativa para dispositivos móviles, web y de escritorio a partir de una única base de código". - Google, <a href="https://flutter.dev/">flutter.dev</a></blockquote><h2 id="-por-qu-deber-as-aprender-flutter"><strong>¿Por qué deberías aprender Flutter?</strong></h2><p>Seleccioné algunas de las razones por las que me gusta Flutter y por las que quiero usarlo el próximo año. Te daré detalles y mis comentarios a continuación.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/07/companies-using-flutter.png" class="kg-image" alt="empresas-usando-flutter" width="600" height="400" loading="lazy"><figcaption><a href="https://flutter.dev/showcase">Empresas que usan Flutter</a></figcaption></figure><p></p><h3 id="f-cil-de-aprender-y-usar"><strong>Fácil de aprender y usar</strong></h3><p>Flutter es un framework moderno, ¡y puedes sentirlo! Es mucho más sencillo crear aplicaciones móviles con él. Si has usado Java, Swift o React Native, notarás cómo Flutter es diferente.</p><p>Personalmente, nunca me gustó el desarrollo de aplicaciones móviles antes de comenzar a usar Flutter.</p><p>Lo que me encanta de Flutter es que puedes crear una aplicación nativa real sin un montón de código.</p><h3 id="compilaci-n-r-pida-m-xima-productividad"><strong>Compilación rápida: Máxima productividad</strong></h3><p>Gracias a Flutter, puedes cambiar tu código y ver los resultados en tiempo real. Se llama recarga en caliente. Solo se necesita un breve período de tiempo después de guardar para actualizar la aplicación en sí.</p><p>Las modificaciones significativas te obligan a recargar la aplicación. Pero si trabajas en el diseño, por ejemplo, y cambias el tamaño de un elemento, ¡es en tiempo real!</p><h3 id="ideal-para-mvp-producto-viable-m-nimo-de-startup"><strong>Ideal para MVP (producto viable mínimo) de startup</strong></h3><p>Si deseas mostrar tu producto a los inversores lo antes posible, Flutter es una buena opción.</p><p>Aquí están mis 4 razones principales para usarlo para tu MVP:</p><ul><li>Es más económico desarrollar una aplicación móvil con Flutter porque no necesitas crear y mantener dos aplicaciones móviles (una para iOS y otra para Android).</li><li>Un desarrollador es todo lo que necesitas para crear tu MVP.</li><li>Es eficaz: No notarás la diferencia entre una aplicación nativa y una aplicación Flutter.</li><li>Es bonito: Puedes usar fácilmente los widgets proporcionados por Flutter y personalizarlos para crear una interfaz de usuario valiosa para tus clientes (puedes encontrar ejemplos de aplicaciones creadas con Flutter a continuación).</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/07/flutter-app-example.gif" class="kg-image" alt="flutter-app-ejemplo" width="600" height="400" loading="lazy"><figcaption><a href="https://github.com/LiveLikeCounter/Flutter-Todolist">Ejemplo de la aplicación Flutter - Lista de tareas pendientes</a></figcaption></figure><h3 id="buena-documentaci-n">Buena documentación</h3><p>Es importante que la nueva tecnología tenga una buena documentación. ¡Pero no siempre es el caso!</p><p>Puedes aprender mucho de la documentación de Flutter, y todo está muy detallado con ejemplos sencillos para casos de uso básicos. Cada vez que tuve un problema con uno de mis widgets en mi código, pude consultar la documentación y la respuesta estaba allí.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/Captura-de-pantalla-2023-04-26-231654.png" class="kg-image" alt="flutter-documentation" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/Captura-de-pantalla-2023-04-26-231654.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2023/04/Captura-de-pantalla-2023-04-26-231654.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/Captura-de-pantalla-2023-04-26-231654.png 1109w" width="1109" height="468" loading="lazy"><figcaption>Arquitectura de documentación de Flutter</figcaption></figure><h3 id="una-comunidad-en-crecimiento"><strong>Una comunidad en crecimiento</strong></h3><p>Flutter tiene una comunidad sólida, ¡y es solo el comienzo!</p><p>Como sabrás, me encanta compartir mis conocimientos y contenido útil sobre programación <a href="https://herewecode.io/">en mi sitio web</a>. Necesito saber que estoy trabajando en una tecnología llena de potencial con muchos patrocinadores.</p><p>Cuando comencé a usar Flutter, lo primero que hice fue buscar comunidades, y para mi sorpresa… hay una cantidad considerable de lugares para intercambiar información de Flutter.</p><p>Te daré algunos ejemplos de lugares que me encanta visitar a diario. No dudes en <a href="https://twitter.com/gaelgthomas/">enviarme un mensaje en Twitter</a> con tus sugerencias.<br></p><ul><li><a href="https://flutterawesome.com/">Flutter Awesome:</a> Una lista increíble que selecciona las mejores bibliotecas y herramientas de Flutter. Este sitio web publica contenido diario con muchos ejemplos, plantillas de aplicaciones, consejos, etc.</li><li><a href="https://github.com/Solido/awesome-flutter">Awesome Flutter:</a> Un repositorio de GitHub (vinculado a Flutter Awesome) con una lista de artículos, videos, componentes, utilidades, etc.</li><li><a href="https://itsallwidgets.com/">It’s all widgets!:</a> Una lista abierta de aplicaciones creadas con Flutter.</li><li><a href="https://medium.com/flutter-community">Flutter Community:</a> Una publicación de Medium donde puedes encontrar artículos, tutoriales y mucho más.</li></ul><h3 id="compatible-con-android-studio-y-vs-code"><strong>Compatible con Android Studio y VS Code</strong></h3><p>Flutter está disponible en diferentes IDEs. Los dos principales editores de código para desarrollar con esta tecnología son Android Studio (IntelliJ) y VS Code.</p><p>Android Studio es un software completo con todo ya integrado. Debes descargar los complementos Flutter y Dart para comenzar.</p><p>VS Code es una herramienta ligera y todo se puede configurar a través de complementos del marketplace.</p><p>Uso Android Studio porque no necesito configurar muchas cosas para que funcione.</p><p>¡Eres libre de elegir tu IDE preferido!</p><h2 id="bonus-extra"><strong>Bonus Extra</strong></h2><h3 id="freelance"><strong>Freelance</strong></h3><p>Si quieres empezar a hacer algún trabajo freelance, deberías pensar en usar Flutter.</p><p>En 2020, creo que esta tecnología va a explotar. Y eso significa que mucha gente buscará desarrolladores que sepan cómo usarlo.</p><p>La mayor plataforma para autónomos de Francia, llamada Malt, publicó recientemente las tendencias tecnológicas de este año. Flutter creció un +303 % en esta plataforma entre 2018 y 2019.</p><p></p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/07/flutter-malt-statistics.png" class="kg-image" alt="flutter-malt-statistics" width="600" height="400" loading="lazy"><figcaption><a href="https://www.malt.com/resources/reports/tech-data-2019/" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Flutter statistics - Malt</a></figcaption></figure><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>Bueno, ¿qué piensas de Flutter? ¿Empezarás a aprenderlo el próximo año?</p><p>Espero que esta introducción te haya interesado y motivado. Siéntete libre de compartir este artículo si te ha gustado.</p><p>Si quieres más contenido como este, puedes <a href="https://twitter.com/gaelgthomas/">seguirme en Twitter</a> , donde tuiteo sobre desarrollo web, superación personal y mi viaje como desarrollador full stack.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Interfaces de Java explicadas con ejemplos ]]>
                </title>
                <description>
                    <![CDATA[ La interfaz en Java es un poco como la Clase, pero con una diferencia significativa: una interface puede tener firmas de métodos, campos y métodos predeterminados. Desde Java 8, también puedes crear métodos predeterminados [https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html]. En el siguiente bloque puedes ver un ejemplo de interfaz: public interface Vehiculo {  ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/interfaces-java-explicadas-con-ejemplos/</link>
                <guid isPermaLink="false">6448d701db9a5007c0849f02</guid>
                
                    <category>
                        <![CDATA[ java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Mon, 01 May 2023 01:13:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/04/5f9c9ce6740569d1a4ca34c5.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/java-interfaces-explained-with-examples/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Java Interfaces Explained with Examples</a>
      </p><p>La interfaz en Java es un poco como la Clase, pero con una diferencia significativa: una<em> </em><code>interface</code> puede tener firmas de métodos, campos y métodos predeterminados. Desde Java 8, también puedes crear <a href="https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html">métodos predeterminados</a>. En el siguiente bloque puedes ver un ejemplo de interfaz:</p><pre><code class="language-java">public interface Vehiculo {
    public String matricula = "";
    public float maxVel
    public void arrancar();
    public void detener();
    default void claxon(){
      System.out.println("Sonando claxon");
   }
}</code></pre><p>La interfaz anterior contiene dos campos, dos métodos y un método predeterminado. Solo, no es de mucha utilidad, pero normalmente se usan junto con las Clases. ¿Cómo? Simple, tienes que asegurarte de que alguna clase lo implemente (<code>implements</code>).</p><pre><code class="language-java">public class Coche implements Vehiculo {
    public void arrancar() {
        System.out.println("arrancando motor...");
    }
    public void detener() {
        System.out.println("deteniendo motor...");
    }
}</code></pre><p>Ahora, hay una <strong><strong><strong><strong>regla básica:</strong></strong></strong></strong> la clase debe implementar <strong><strong><strong><strong>todos</strong></strong></strong></strong> los métodos que hay en la interfaz. Los métodos deben tener <em><em>exactamente la misma</em></em> firma (nombre, parámetros y excepciones) como se describe en la interfaz. Sin embargo, la clase <em><em>no</em></em> necesita declarar los campos, solo los métodos.</p><h2 id="instancias-de-una-interfaz"><strong><strong><strong>Instancias de una interfaz</strong></strong></strong></h2><p>Una vez que creas una clase Java que <code>implements</code> (implementa) cualquier interfaz, se puede hacer referencia a la instancia del objeto como una instancia de la interfaz. Este concepto es similar al de creación de instancias de herencia.</p><pre><code class="language-java">// siguiendo nuestro ejemplo anterior

Vehiculo tesla = new Coche();

tesla.arrancar(); // arrancar el motor...</code></pre><p>Una interfaz <strong><strong><strong><strong>no puede</strong></strong></strong></strong> contener métodos constructores. Por lo tanto, <strong><strong><strong><strong>no puede</strong></strong></strong>s</strong> crear una instancia de una interfaz en sí. Debes crear una instancia de alguna clase que implemente una interfaz para hacer referencia a ella.</p><p>Piensa en las interfaces como un formulario de contrato en blanco o una plantilla.</p><p>¿Qué puedes hacer con esta función? ¡Polimorfismo! ¡Puedes usar solo interfaces para referirte a instancias de objetos!</p><pre><code class="language-java">class Camion implements Vehiculo {
    public void arrancar() {
        System.out.println("arrancando el motor del camión...");
    }
    public void detener() {
        System.out.println("deteniendo el motor del camión...");
    }
}

class Arrancador {
    // método estático, se puede llamar sin instanciar la clase
    public static void arrancarMotor(Vehiculo vehiculo) {
        vehiculo.arrancar();
    }
}

Vehiculo tesla = new Coche();
Vehiculo tata = new Camion();

Arrancador.arrancarMotor(tesla); // arrancando motor...
Arrancador.arrancarMotor(tata); // arrancar el motor del camión...</code></pre><h2 id="pero-qu-hay-de-las-m-ltiples-interfaces"><strong><strong><strong>Pero, ¿qué hay de </strong>las <strong>múltiples interfaces?</strong></strong></strong></h2><p>Sí, puedes implementar varias interfaces en una sola clase. Mientras estaba en <a href="https://forum.freecodecamp.com/t/java-docs-inheritance">Herencia</a> dentro de las clases estaba restringido a heredar solo una clase, aquí puedes ampliar cualquier cantidad de interfaces. Pero no olvides implementar <em><em>todos</em></em> los métodos de todas las interfaces, de lo contrario, la compilación fallará.</p><pre><code class="language-java">public interface GPS {
    public void obtenerCoordenadas();
}

public interface Radio {
    public void iniciarRadio();
    public void detenerRadio();
}

public class Smartphone implements GPS,Radio {
    public void obtenerCoordenadas() {
        // devuelve algunas coordenadas
    }
    public void iniciarRadio() {
      // iniciar Radio
    }
    public void detenerRadio() {
        // detener Radio
    }
}</code></pre><h2 id="algunas-caracter-sticas-de-las-interfaces"><strong><strong><strong>Algunas características de las interfaces</strong></strong></strong></h2><ul><li>Puedes colocar variables dentro de una interfaz, aunque no será una decisión sensata, ya que las clases no están obligadas a tener la misma variable. En resumen, ¡evita colocar variables!</li><li>Todas las variables y métodos en una interfaz son públicos, incluso si omites la palabra clave <code>public</code>.</li><li>Una interfaz no puede especificar la implementación de un método en particular. Depende de las Clases hacerlo. Aunque ha habido una excepción reciente (ver más abajo).</li><li>Si una clase implementa varias interfaces, existe una posibilidad remota de superposición de la firma del método. Dado que Java no permite múltiples métodos de la misma firma exacta, podría generar problemas. Consulta <a href="http://stackoverflow.com/questions/2598009/method-name-collision-in-interface-implementation-java" rel="nofollow">esta pregunta</a> para obtener más información.</li></ul><h2 id="m-todos-predeterminados-de-la-interfaz"><strong><strong><strong>Métodos predeterminados de la interfaz</strong></strong></strong></h2><p>Antes de Java 8, no teníamos forma de dirigir una interfaz para que tuviera una implementación de método particular, lo que genera mucha confusión y roturas de código si la definición de una interfaz cambia repentinamente.</p><p>Pongamos que escribes una biblioteca de código abierto, que contiene una interfaz. Digamos que tus clientes, es decir, prácticamente todos los desarrolladores de todo el mundo, lo están usando mucho y están contentos. Ahora has tenido que actualizar la biblioteca agregando una nueva definición de método a la interfaz para admitir una nueva característica. Pero eso rompería <em><em>todas</em></em> las compilaciones, ya que todas las clases que implementan esa interfaz tienen que cambiar ahora. ¡Qué catástrofe!</p><p>Afortunadamente, Java 8 ahora nos proporciona métodos <code>default</code> (predeterminados) para interfaces. ¡Un método <code>default</code> <em><em>puede</em></em> contener su propia implementación <em><em>directamente</em></em> dentro de la interfaz! Entonces, si una Clase no implementa un método predeterminado, el compilador tomará la implementación mencionada dentro de la Interfaz. Bonito, ¿no? Entonces, en tu biblioteca, puede agregar cualquier cantidad de métodos predeterminados en las interfaces sin miedo a estropear nada.</p><pre><code class="language-java">public interface GPS {
    public void obtenerCoordenadas();
    default public void obtenerCoordenadasAproximadas() {
        // implementación para devolver coordenadas de fuentes aproximadas
        // como wifi y móvil
        System.out.println("Obteniendo coordenadas aproximadas por wifi y GSM...");
    }
}

public interface Radio {
    public void iniciarRadio();
    public void detenerRadio();
}

public class Smartphone implements GPS,Radio {
    public void obtenerCoordenadas() {
        // devuelve algunas coordenadas
    }
    public void iniciarRadio() {
      // iniciar Radio
    }
    public void detenerRadio() {
        // detener Radio
    }

    // sin implementación de getRoughCoordinates()
}

Smartphone motoG = new Smartphone();
motog.obtenerCoordenadasAproximadas(); // Obteniendo coordenadas aproximadas por wifi y GSM...</code></pre><p><strong><strong>Pero, ¿qué sucede si dos interfaces tienen la misma firma de método?</strong></strong></p><p>Gran pregunta. En ese caso, si no proporcionas la implementación en la clase, el pobre compilador se confundirá y simplemente fallará. También debes proporcionar una implementación de método predeterminada dentro de la Clase. También hay una forma ingeniosa de usar <code>super</code> para llamar a la implementación que te gusta:</p><pre><code class="language-java">public interface Radio {
    // public void iniciarRadio();
    // public void detenerRadio();

    default public void siguiente() {
        System.out.println("Siguiente emisora de Radio");
    }
}

public interface ReproductorMusica {
    // public void iniciar();
    // public void pausar();
    // public void detener();

    default public void siguiente() {
        System.out.println("Siguiente canción del Reproductor de Música");
    }
}

public class Smartphone implements Radio, ReproductorMusica {
    public void siguiente() {
        // Supongamos que deseas llamar a siguiente del ReproductorMusica
        ReproductorMusica.super.siguiente();
    }
}

Smartphone motoG = new Smartphone();
motoG.siguiente();  // Siguiente desde ReproductorMusica</code></pre><h2 id="m-todos-est-ticos-en-interfaces"><strong><strong><strong>Métodos estáticos en interfaces</strong></strong></strong></h2><p>Otra novedad de Java 8 es la capacidad de agregar métodos estáticos a las interfaces. Los métodos estáticos en interfaces son casi idénticos a los métodos estáticos en clases concretas. La única gran diferencia es que los métodos <code>static</code> no se heredan en las clases que implementan la interfaz. Esto significa que se hace referencia a la interfaz cuando se llama al método estático, no a la clase que lo implementa.</p><pre><code class="language-java">interface ReproductorMusica {
  public static void comercial(String patrocinador) {
    System.out.println("Nuevo mensaje de " + patrocinador);
  }
  
  public void play();
}


class Smartphone implements ReproductorMusica {
	public void reproducir() {
		System.out.println("Reproduciendo desde el Smartphone");
	}
}

class Main {
  public static void main(String[] args) {
    Smartphone motoG = new Smartphone();
    ReproductorMusica.comercial("Motorola"); 
    // Llamada a la interfaz no a la clase implementada
    // motoG.comercial("Motorola");  // Esto causaría un error de compilación
  }
}</code></pre><h2 id="heredar-una-interfaz"><strong><strong><strong>Heredar una interfaz</strong></strong></strong></h2><p>También es posible en Java que una interfaz herede <em><em>otra</em></em> interfaz usando, la palabra clave <code>extends</code>:</p><pre><code class="language-java">public interface Reproductor {
    public void iniciar();
    public void pausar();
    public void detener();
}

public interface ReproductorMusica extends Reproductor {
    default public void siguiente() {
        System.out.println("siguiente canción del Reproductor de Música");
    }
}</code></pre><p>Eso significa que la clase que implementa <code>ReproductorMusica</code> tiene que implementar <em><em>todos</em></em> los métodos de <code>ReproductorMusica</code> así como los de <code>Reproductor</code>:</p><pre><code class="language-java">public class SmartPhone implements ReproductorMusica {
    public void iniciar() {
        System.out.println("iniciar");
    }
    public void detener() {
        System.out.println("detener");
    }
    public void pausar() {
        System.out.println("pausar");
    }
}</code></pre><p>¡Ahora ya tienes una buena comprensión de las interfaces de Java! Obtén información sobre las clases abstractas para ver cómo Java te brinda otra forma de definir contratos.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Algoritmos de ordenación explicados con ejemplos en JavaScript, Python, Java y C++ ]]>
                </title>
                <description>
                    <![CDATA[ ¿Qué es un algoritmo de ordenación? Los algoritmos de ordenación son un conjunto de instrucciones que toman un arreglo o lista como entrada y organizan los elementos en un orden particular. Las ordenaciones suelen ser numéricas o una forma de orden alfabético (o lexicográfico), y pueden ser en orden ascendente ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/algoritmos-de-ordenacion-explicados-con-ejemplos-en-javascript-python-java-y-c/</link>
                <guid isPermaLink="false">64455d642ef44808032fa708</guid>
                
                    <category>
                        <![CDATA[ Algoritmos ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Mon, 01 May 2023 00:45:12 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/04/5f9c9ede740569d1a4ca3f9d-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/sorting-algorithms-explained-with-examples-in-python-java-and-c/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Sorting Algorithms Explained with Examples in JavaScript, Python, Java, and C++</a>
      </p><h2 id="-qu-es-un-algoritmo-de-ordenaci-n"><strong>¿Qué es un algoritmo de ordenación?</strong></h2><p>Los algoritmos de ordenación son un conjunto de instrucciones que toman un arreglo o lista como entrada y organizan los elementos en un orden particular.</p><p>Las ordenaciones suelen ser numéricas o una forma de orden alfabético (o lexicográfico), y pueden ser en orden ascendente (AZ, 0-9) o descendente (ZA, 9-0).</p><h2 id="por-qu-los-algoritmos-de-ordenaci-n-son-importantes"><strong>Por qué los algoritmos de ordenación son importantes</strong></h2><p>Dado que a menudo pueden reducir la complejidad de un problema, los algoritmos de ordenación son muy importantes en informática. Estos algoritmos tienen aplicaciones directas en algoritmos de búsqueda, algoritmos de bases de datos, métodos divide y vencerás, algoritmos de estructura de datos y muchos más.</p><h2 id="compensaciones-de-los-algoritmos-de-ordenaci-n"><strong>Compensaciones de los algoritmos de </strong>ordenación</h2><p>Al elegir un algoritmo de ordenación, se deben hacer algunas preguntas: ¿Cuán grande es la colección que se ordena? ¿Cuánta memoria hay disponible? ¿La colección necesita crecer?</p><p>Las respuestas a estas preguntas pueden determinar qué algoritmo funcionará mejor para cada situación. Algunos algoritmos como la ordenación por combinación pueden necesitar mucho espacio o memoria para ejecutarse, mientras que la ordenación por inserción no siempre es la más rápida, pero no requiere muchos recursos para ejecutarse.</p><p>Debes determinar cuáles son tus requisitos y considerar las limitaciones de tu sistema antes de decidir qué algoritmo de ordenación usar.</p><h2 id="algunos-algoritmos-de-ordenaci-n-comunes"><strong>Algunos algoritmos de </strong>ordenación<strong> comunes</strong></h2><p>Algunos de los algoritmos de ordenación más comunes son:</p><ul><li>Selection sort (selección)</li><li>Bubble sort (burbuja)</li><li>Insertion sort (inserción)</li><li>Merge sort (combinación)</li><li>Quick sort (rápida)</li><li>Heap sort (montón)</li><li>Counting sort (conteo)</li><li>Radix sort (raíz)</li><li>Bucket sort (cubo)</li></ul><p>Pero antes de entrar en cada uno de estos, aprendamos un poco más sobre qué clasifica a un algoritmo de ordenación.</p><h2 id="clasificaci-n-de-un-algoritmo-de-ordenaci-n"><strong>Clasificación de un algoritmo de </strong>ordenación</h2><p>Los algoritmos de ordenación se pueden clasificar en función de los siguientes parámetros:</p><ol><li><strong><strong>La cantidad de interca</strong>m<strong>bios o inversiones requeridas:</strong></strong> Esta es la cantidad de veces que el algoritmo intercambia elementos para ordenar la entrada. La ordenación por selección requiere el número mínimo de intercambios.</li><li><strong><strong>El número de comparaciones:</strong></strong> Este es el número de veces que el algoritmo compara elementos para ordenar la entrada. Usando <a href="https://guide.freecodecamp.org/computer-science/notation/big-o-notation/">la notación Big-O</a> , los ejemplos de algoritmos de ordenación enumerados anteriormente requieren al menos <code>O(nlogn)</code>comparaciones en el mejor de los casos y <code>O(n^2)</code> comparaciones en el peor de los casos para la mayoría de los resultados.</li><li><strong><strong>Ya sea que usen recursividad o no:</strong></strong> Algunos algoritmos de ordenación, como la ordenación rápida, usan técnicas recursivas para ordenar la entrada. Otros algoritmos de ordenación, como la ordenación por selección o la ordenación por inserción, utilizan técnicas no recursivas. Por último, algunos algoritmos de ordenación, como la ordenación por fusión, utilizan técnicas tanto recursivas como no recursivas para ordenar la entrada.</li><li><strong><strong>Ya sean estables o inestables:</strong></strong> Los algoritmos de ordenación estables mantienen el orden relativo de los elementos con valores iguales o claves. Los algoritmos de ordenación inestables no mantienen el orden relativo de los elementos con valores/claves iguales.<br><br>Por ejemplo, imagina que tienes el arreglo de entrada <code>[1, 2, 3, 2, 4]</code>. Y para ayudar a diferenciar entre los dos valores iguales, <code>2</code> actualicémoslos a <code>2a</code> y <code>2b</code>, creando el arreglo de entrada <code>[1, 2a, 3, 2b, 4]</code>.<br><br>Los algoritmos de ordenación estables mantendrán el orden de <code>2a</code> y <code>2b</code>, lo que significa que el arreglo de salida será <code>[1, 2a, 2b, 3, 4]</code>. Los algoritmos de ordenación inestables no mantienen el orden de los valores iguales y el arreglo de salida puede ser <code>[1, 2b, 2a, 3, 4]</code>.<br><br>La ordenación por inserción, la ordenación por fusión y la ordenación por burbuja son estables. La ordenación en montón y la ordenación rápida son inestables.</li><li><strong><strong>La cantidad de espacio adicional requerido:</strong></strong> Algunos algoritmos de ordenación pueden ordenar una lista sin crear una lista completamente nueva. Estos se conocen como algoritmos de ordenación en el lugar y requieren un <code>O(1)</code> espacio adicional constante para la ordenación. Mientras tanto, los algoritmos de ordenación fuera de lugar crean una nueva lista durante la ordenación.<br><br>La ordenación por inserción y la ordenación rápida son algoritmos de ordenación en el lugar, ya que los elementos se mueven alrededor de un punto de pivote y no usan un arreglo separado.<br><br>Merge sort es un ejemplo de un algoritmo de ordenación fuera del lugar, ya que el tamaño de la entrada debe asignarse de antemano para almacenar la salida durante el proceso de ordenación, lo que requiere memoria adicional.</li></ol><h2 id="bucket-sort-ordenaci-n-de-cubo-"><strong><strong>Bucket Sort</strong> (O</strong>rdenación<strong> de cubo)</strong></h2><p>La ordenación de cubos es un algoritmo de ordenación por comparación que opera en elementos dividiéndolos en diferentes cubos y luego ordenando estos cubos individualmente. Cada depósito se ordena individualmente utilizando un algoritmo de ordenación independiente, como la ordenación por inserción, o aplicando el algoritmo de ordenación de cubos de forma recursiva.</p><p>La ordenación de cubos es principalmente útil cuando la entrada se distribuye uniformemente en un rango. Por ejemplo, imagina que tienes una gran variedad de enteros de punto flotante distribuidos uniformemente entre un límite superior e inferior.</p><p>Puedes usar otro algoritmo de ordenación, como la ordenación por combinación, la ordenación por montones o la ordenación rápida. Sin embargo, esos algoritmos garantizan una complejidad de tiempo en el mejor de los casos de <code>O(nlogn)</code>.</p><p>Usando la ordenación de cubos, la ordenación del mismo arreglo se puede completar a <code>O(n)</code>tiempo.</p><h3 id="pseudoc-digo-para-ordenaci-n-de-cubo-"><strong>Pseudocódigo para </strong>ordenación<strong> de cubo:</strong></h3><pre><code>void bucketSort(float[] a,int n)

{

    for(each floating integer 'x' in n)

    {
        insert x into bucket[n*x]; 
    }

    for(each bucket)

    {
        sort(bucket);
    }

}
</code></pre><h2 id="counting-sort-ordenaci-n-de-conteo-"><strong><strong>Counting Sort</strong> (</strong>Ordenación<strong> de conteo)</strong></h2><p>El algoritmo de ordenación por conteo funciona creando primero una lista de los conteos u ocurrencias de cada valor único en la lista. Luego crea una lista ordenada final basada en la lista de conteos.</p><p>Una cosa importante que debes recordar es que la ordenación por conteo solo se puede usar cuando conoces de antemano el rango de valores posibles en la entrada.</p><h3 id="ejemplo-"><strong>Ejemplo:</strong></h3><pre><code>Digamos que tienes una lista de números enteros del 0 al 5:
 
input = [2, 5, 3, 1, 4, 2]

Primero, debes crear una lista de recuentos para cada valor único en
la lista `entrada`. Como sabes que el rango de la `entrada` es de 0 a
5, puedes crear una lista con cinco marcadores de posición para los valores del 0 al 5, respectivamente:

count = [0, 0, 0, 0, 0, 0]
  # val: 0  1  2  3  4  5

Luego, revisas la lista `input` e iteras el índice para cada valor en uno.

Por ejemplo, el primer valor en la lista `input` es 2, por lo que agrega uno
al valor en el segundo índice de la lista `count`, que representa
el valor 2:

count = [0, 0, 1, 0, 0, 0]
  # val: 0  1  2  3  4  5
       
El siguiente valor en la lista `input` es 5, por lo que agrega uno al valor en el último índice de la lista `count`, que representa el valor 5:

count = [0, 0, 1, 0, 0, 1]
  # val: 0  1  2  3  4  5

Continúa hasta que tengas el recuento total de cada valor en la `entrada`
lista:

count = [0, 1, 2, 1, 1, 1]
  # val: 0  1  2  3  4  5

Finalmente, dado que sabes cuántas veces cada valor en la lista `input`
aparece, puedes crear fácilmente una lista de `salida` ordenada. Bucle a través de la lista `recuento`, y para cada recuento, agrega el valor correspondiente (0 - 5) al arreglo `output` tantas veces.

Por ejemplo, no había 0 en la lista de 'entradas', pero había una aparición del valor 1, por lo que agrega ese valor al arreglo `output`
una vez:

output = [1]

Luego hubo dos apariciones del valor 2, por lo que las agrega a la
lista `output`:

output = [1, 2, 2]

Y así sucesivamente hasta que tengas la lista final ordenada de "salida" (output):

output = [1, 2, 2, 3, 4, 5]
</code></pre><h3 id="propiedades"><strong>Propiedades</strong></h3><ul><li>Complejidad de espacio:<code>O(k)</code></li><li>Rendimiento del mejor caso:<code>O(n+k)</code></li><li>Rendimiento del caso promedio:<code>O(n+k)</code></li><li>Rendimiento en el peor de los casos:<code>O(n+k)</code></li><li>Estable: Sí ( <code>k</code>es el rango de los elementos en el arreglo)</li></ul><h3 id="implementaci-n-en-javascript"><strong>Implementación en JavaScript</strong></h3><pre><code class="language-js">let numbers = [1, 4, 1, 2, 7, 5, 2];
let count = [];
let output =[];
let i = 0;
let max = Math.max(...numbers);

// inicializa el contador
for (i = 0; i &lt;= max; i++) {
  count[i] = 0;
}

// inicializa el arreglo de salida
for (i = 0; i &lt; numbers.length; i++) {
  output[i] = 0;
}

for (i = 0; i &lt; numbers.length; i++) {
  count[numbers[i]]++;
}

for (i = 1; i &lt; count.length; i++) {
  count[i] += count[i-1];
}

for (i = numbers.length - 1; i &gt;= 0; i--) { 
  output[--count[numbers[i]]] = numbers[i];
}

// arreglo ordenado de salida
for (i = 0; i &lt; output.length; i++) {
  console.log(output[i]);
}</code></pre><h3 id="implementaci-n-de-c-"><strong>Implementación de C++</strong></h3><pre><code class="language-cpp">#include &lt;iostream&gt;

#include &lt;vector&gt;

void countSort(int upperBound, int lowerBound, std::vector &lt; int &gt; numbersToSort) 
// Límites inferior y superior de los números en el vector
{
  int i;
  int range = upperBound - lowerBound; // Crea un rango lo suficientemente grande para obtener todos los números entre el mínimo y el máximo
  std::vector &lt; int &gt; counts(range + 1); // Inicializar conteos del tamaño del rango
  std::fill(counts.begin(), counts.end(), 0); // Rellenar vector de ceros
  std::vector &lt; int &gt; storedNumbers(numbersToSort.size()); // Inicializar los números almacenados del mismo tamaño que el vector de entrada
  std::fill(storedNumbers.begin(), storedNumbers.end(), 0); // Rellenar vector de números almacenados de ceros
  for (i = 0; i &lt; numbersToSort.size(); i++) {
    int index = numbersToSort[i] - lowerBound; // Por ejemplo, si 5 es el límite inferior y numberToSort[i] es 5, el índice será 0 y el
    counts[index] += 1; // recuento de 5 se almacenará en recuentos[0]
  }

  for (i = 1; i &lt; counts.size(); i++) {
    counts[i] += counts[i - 1];
  }

  for (i = numbersToSort.size() - 1; i &gt;= 0; i--) { // Copiar elementos de numbersToSort a storedNumbers según el conteo
    storedNumbers[--counts[numbersToSort[i] - lowerBound]] = numbersToSort[i];
  }

  for (i = 0; i &lt; storedNumbers.size(); i++) {
    std::cout &lt;&lt; storedNumbers[i];
    if (i != storedNumbers.size() - 1)
      std::cout &lt;&lt; ", ";
  }
  std::cout &lt;&lt; std::endl;
}</code></pre><h3 id="implementaci-n-en-swift"><strong>Implementación en Swift</strong></h3><pre><code class="language-swift">func countingSort(_ array: [Int]) {
  // Crea un arreglo para almacenar el conteo de cada elemento
  let maxElement = array.max() ?? 0
  var countArray = [Int](repeating: 0, count: Int(maxElement + 1))
  
  for element in array {
    countArray[element] += 1
  }
  
  for i in 1 ..&lt; countArray.count {
    countArray[i] += countArray[i-1];
  }
  
  var sortedArray = [Int](repeating: 0, count: array.count)
  
  // copia elementos del arreglo a sortedArray de acuerdo con el conteo
  for i in (0 ..&lt; array.count) .reversed() {
    countArray[array[i]] -= 1
    sortedArray[countArray[array[i]]] = array[i];
  }
  
  print(sortedArray)
}</code></pre><h2 id="insertion-sort-ordenaci-n-de-inserci-n-"><strong><strong>Insertion Sort</strong> (</strong>Ordenación<strong> de inserción)</strong></h2><p>La ordenación por inserción es un algoritmo de ordenación simple para una pequeña cantidad de elementos.</p><h3 id="ejemplo--1"><strong>Ejemplo:</strong></h3><p>En la ordenación por inserción, compara el elemento <code>key</code> con los elementos anteriores. Si los elementos anteriores son mayores que el elemento <code>key</code>, mueve el elemento anterior a la siguiente posición.</p><p>Comienza desde el índice 1 hasta el tamaño del arreglo de entrada.</p><p>[ 8 3 5 1 4 2 ]</p><p>Paso 1 :</p><pre><code>      key = 3 //a partir del 1er índice.

      Aquí `key`(clave) se comparará con los elementos anteriores.

      En este caso, `key` se compara con 8. como 8 &gt; 3, mueve el elemento 8
      a la siguiente posición e inserta `key` en la posición anterior.

      Result: [ 3 8 5 1 4 2 ]
</code></pre><p>Paso 2 :</p><figure class="kg-card kg-image-card"><img src="https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/2.png?raw=true" class="kg-image" alt="[ 3 8 5 1 4 2 ]" width="600" height="400" loading="lazy"></figure><pre><code>      key = 5 //2º índice

      8 &gt; 5 // mueve 8 al segundo índice e inserta 5 en el primer índice.

      Result: [ 3 5 8 1 4 2 ]
</code></pre><p>Paso 3 :</p><figure class="kg-card kg-image-card"><img src="https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/3.png?raw=true" class="kg-image" alt="[ 3 5 8 1 4 2 ]" width="600" height="400" loading="lazy"></figure><pre><code>      //3er índice

      8 &gt; 1     =&gt; [ 3 5 1 8 4 2 ]  

      5 &gt; 1     =&gt; [ 3 1 5 8 4 2 ]

      3 &gt; 1     =&gt; [ 1 3 5 8 4 2 ]

      Result: [ 1 3 5 8 4 2 ]
</code></pre><p>Paso 4 :</p><figure class="kg-card kg-image-card"><img src="https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/4.png?raw=true" class="kg-image" alt="[ 1 3 5 8 4 2 ]" width="600" height="400" loading="lazy"></figure><pre><code>      key = 4 // 4º índice

      8 &gt; 4   =&gt; [ 1 3 5 4 8 2 ]

      5 &gt; 4   =&gt; [ 1 3 4 5 8 2 ]

      3 &gt; 4   ≠&gt;  stop

      Result: [ 1 3 4 5 8 2 ]
</code></pre><p>Paso 5 :</p><figure class="kg-card kg-image-card"><img src="https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/5.png?raw=true" class="kg-image" alt="[ 1 3 4 5 8 2 ]" width="600" height="400" loading="lazy"></figure><pre><code>      key = 2 // 5º índice

      8 &gt; 2   =&gt; [ 1 3 4 5 2 8 ]

      5 &gt; 2   =&gt; [ 1 3 4 2 5 8 ]

      4 &gt; 2   =&gt; [ 1 3 2 4 5 8 ]

      3 &gt; 2   =&gt; [ 1 2 3 4 5 8 ]

      1 &gt; 2   ≠&gt; stop

      Result: [1 2 3 4 5 8]
</code></pre><figure class="kg-card kg-image-card"><img src="https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/6.png?raw=true" class="kg-image" alt="[ 1 2 3 4 5 8 ]" width="600" height="400" loading="lazy"></figure><p>El algoritmo que se muestra a continuación es una versión ligeramente optimizada para evitar cambiar el elemento <code>key</code> &nbsp;en cada iteración. Aquí, el elemento &nbsp;<code>key</code> &nbsp; se intercambiará al final de la iteración (paso).</p><pre><code>    InsertionSort(arr[])
      for j = 1 to arr.length
         key = arr[j]
         i = j - 1
         while i &gt; 0 and arr[i] &gt; key
            arr[i+1] = arr[i]
            i = i - 1
         arr[i+1] = key
</code></pre><p>Aquí hay una implementación detallada en JavaScript:</p><pre><code class="language-js">function insertion_sort(A) {
    var len = array_length(A);
    var i = 1;
    while (i &lt; len) {
        var x = A[i];
        var j = i - 1;
        while (j &gt;= 0 &amp;&amp; A[j] &gt; x) {
            A[j + 1] = A[j];
            j = j - 1;
        }
        A[j+1] = x;
        i = i + 1;
    }
}
</code></pre><p>A continuación se muestra una implementación rápida en Swift:</p><pre><code class="language-swift">  var array = [8, 3, 5, 1, 4, 2]

  func insertionSort(array:inout Array&lt;Int&gt;) -&gt; Array&lt;Int&gt;{
      for j in 0..&lt;array.count {
          let key = array[j]
          var i = j-1

          while (i &gt; 0 &amp;&amp; array[i] &gt; key){
              array[i+1] = array[i]
              i = i-1
          }
          array[i+1] = key
      }
      return array
  }
</code></pre><p>El ejemplo de Java se muestra a continuación:</p><pre><code class="language-java">public int[] insertionSort(int[] arr)
      for (j = 1; j &lt; arr.length; j++) {
         int key = arr[j]
         int i = j - 1
         while (i &gt; 0 and arr[i] &gt; key) {
            arr[i+1] = arr[i]
            i -= 1
         }
         arr[i+1] = key
      }
      return arr;
</code></pre><p>Y en c...</p><pre><code class="language-c">void insertionSort(int arr[], int n) 
{ 
   int i, key, j; 
   for (i = 1; i &lt; n; i++) 
   { 
       key = arr[i]; 
       j = i-1;
       while (j &gt;= 0 &amp;&amp; arr[j] &gt; key) 
       { 
           arr[j+1] = arr[j]; 
           j = j-1; 
       } 
       arr[j+1] = key; 
   } 
} 
</code></pre><h3 id="propiedades-"><strong>Propiedades:</strong></h3><ul><li>Complejidad de espacio: O(1)</li><li>Complejidad de tiempo: O(n), O(n* n), O(n* n) para los mejores, promedios y peores casos respectivamente.</li><li>Mejor caso: El arreglo ya está ordenado </li><li>Caso promedio: El arreglo se ordena aleatoriamente</li><li>En el peor de los casos: El arreglo se ordena de forma inversa. </li><li>Ordenación en el lugar: Sí</li><li>Estable: Sí</li></ul><h2 id="heapsort-ordenaci-n-por-montones-"><strong>Heapsort (Ordenación por montones)</strong></h2><p>Heapsort es un algoritmo de ordenación eficiente basado en el uso de montones máximos/mínimos. Un montón es una estructura de datos basada en un árbol que satisface la propiedad del montón, es decir, para un montón máximo, la clave de cualquier nodo es menor o igual que la clave de su padre (si tiene un padre).</p><p>Esta propiedad se puede aprovechar para acceder al elemento máximo en el montón en tiempo O (logn) usando el método maxHeapify. Realizamos esta operación n veces, cada vez que movemos el elemento máximo en el montón a la parte superior del montón y lo extraemos del montón y lo colocamos en un arreglo ordenado. Por lo tanto, después de n iteraciones, tendremos una versión ordenada del arreglo de entrada. </p><p>El algoritmo no es un algoritmo en el lugar y requeriría que se construyera primero una estructura de datos de montón. El algoritmo también es inestable, lo que significa que al comparar objetos con la misma clave, no se conservará el orden original.</p><p>Este algoritmo se ejecuta en tiempo O(nlogn) y espacio adicional O(1) [O(n) incluido el espacio requerido para almacenar los datos de entrada] ya que todas las operaciones se realizan completamente en el lugar.</p><p>La complejidad de tiempo del caso mejor, peor y promedio de Heapsort es O (nlogn). Aunque heapsort tiene una mejor complejidad en el peor de los casos que quicksort, una ordenación rápida bien implementada se ejecuta más rápido en la práctica. Este es un algoritmo basado en la comparación, por lo que se puede usar para conjuntos de datos no numéricos en la medida en que se pueda definir alguna relación (propiedad del montón) sobre los elementos.</p><p>Una implementación en Java es como se muestra a continuación:</p><pre><code class="language-java">import java.util.Arrays;
public class Heapsort {

	public static void main(String[] args) {
		//test array
        //arreglo de prueba
		Integer[] arr = {1, 4, 3, 2, 64, 3, 2, 4, 5, 5, 2, 12, 14, 5, 3, 0, -1};
		String[] strarr = {"hope you find this helpful!", "wef", "rg", "q2rq2r", "avs", "erhijer0g", "ewofij", "gwe", "q", "random"};
		arr = heapsort(arr);
		strarr = heapsort(strarr);
		System.out.println(Arrays.toString(arr));
		System.out.println(Arrays.toString(strarr));
	}
	
	//O(nlogn) TIME, O(1) SPACE, NOT STABLE
    //O(nlogn) TIEMPO, O(1) ESPACIO, NO ESTABLE
	public static &lt;E extends Comparable&lt;E&gt;&gt; E[] heapsort(E[] arr){
		int heaplength = arr.length;
		for(int i = arr.length/2; i&gt;0;i--){
			arr = maxheapify(arr, i, heaplength);
		}
		
		for(int i=arr.length-1;i&gt;=0;i--){
			E max = arr[0];
			arr[0] = arr[i];
			arr[i] = max;
			heaplength--;
			arr = maxheapify(arr, 1, heaplength);
		}
		
		return arr;
	}
	
	//Creates maxheap from array
//Crea maxheap a partir de un arreglo
	public static &lt;E extends Comparable&lt;E&gt;&gt; E[] maxheapify(E[] arr, Integer node, Integer heaplength){
		Integer left = node*2;
		Integer right = node*2+1;
		Integer largest = node;
		
		if(left.compareTo(heaplength) &lt;=0 &amp;&amp; arr[left-1].compareTo(arr[node-1]) &gt;= 0){
			largest = left;
		}
		if(right.compareTo(heaplength) &lt;= 0 &amp;&amp; arr[right-1].compareTo(arr[largest-1]) &gt;= 0){
			largest = right;
		}	
		if(largest != node){
			E temp = arr[node-1];
			arr[node-1] = arr[largest-1];
			arr[largest-1] = temp;
			maxheapify(arr, largest, heaplength);
		}
		return arr;
	}
}
</code></pre><p>Implementación en C++</p><pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;
void heapify(int arr[], int n, int i) 
{ 
    int largest = i; 
    int l = 2*i + 1;  
    int r = 2*i + 2;
    if (l &lt; n &amp;&amp; arr[l] &gt; arr[largest]) 
        largest = l;
    if (r &lt; n &amp;&amp; arr[r] &gt; arr[largest]) 
        largest = r;
    if (largest != i) 
    { 
        swap(arr[i], arr[largest]); 
  
        
        heapify(arr, n, largest); 
    } 
} 
  
 
void heapSort(int arr[], int n) 
{ 
    
    for (int i = n / 2 - 1; i &gt;= 0; i--) 
        heapify(arr, n, i); 
  
    
    for (int i=n-1; i&gt;=0; i--) 
    { 

        swap(arr[0], arr[i]); 
  
        
        heapify(arr, i, 0); 
    } 
} 
void printArray(int arr[], int n) 
{ 
    for (int i=0; i&lt;n; ++i) 
        cout &lt;&lt; arr[i] &lt;&lt; " "; 
    cout &lt;&lt; "\n"; 
} 
int main() 
{ 
    int arr[] = {12, 11, 13, 5, 6, 7}; 
    int n = sizeof(arr)/sizeof(arr[0]); 
  
    heapSort(arr, n); 
  
    cout &lt;&lt; "Sorted array is \n"; 
    printArray(arr, n); 
}
</code></pre><h2 id="ordenaci-n-radix">Ordenación<strong> Radix</strong></h2><p>Requisito previo: Ordenar por conteo</p><p>QuickSort, MergeSort y HeapSort son algoritmos de ordenación basados ​​en comparaciones. CountSort no lo es. Tiene la complejidad de O(n+k), donde k es el elemento máximo del arreglo de entrada. Entonces, si k es O(n), CountSort se convierte en una ordenación lineal, que es mejor que los algoritmos de ordenación basados ​​en comparación que tienen una complejidad de tiempo O(nlogn).</p><p>La idea es extender el algoritmo CountSort para obtener una mejor complejidad de tiempo cuando k pasa a O(n2). Aquí viene la idea de Radix Sort.</p><h3 id="el-algoritmo-"><strong>El algoritmo:</strong></h3><p>Para cada dígito i donde i varía del dígito menos significativo al dígito más significativo de un número, ordena el arreglo de entrada utilizando el algoritmo de ordenación de acuerdo con el i-ésimo dígito. Usamos la ordenación por conteo porque es una ordenación estable.</p><p>Ejemplo: Supón que el arreglo de entrada es:</p><p>10, 21, 17, 34, 44, 11, 654, 123</p><p>Según el algoritmo, ordenaremos el arreglo de entrada según el dígito de uno (dígito menos significativo).</p><p>0: 10<br>1: 21 11<br>2:<br>3: 123<br>4: 34 44 654<br>5:<br>6:<br>7: 17<br>8:<br>9:</p><p>Entonces, el arreglo se convierte en 10, 21, 11, 123, 24, 44, 654, 17.</p><p>Ahora, ordenaremos según el dígito de las decenas:</p><p>0:<br>1: 10 11 17<br>2: 21 123<br>3: 34<br>4: 44<br>5: 654<br>6:<br>7:<br>8:<br>9:</p><p>Ahora, el arreglo se convierte en: 10, 11, 17, 21, 123, 34, 44, 654.</p><p>Finalmente, ordenamos según el dígito de las centenas (dígito más significativo):</p><p>0: 010 011 017 021 034 044<br>1: 123<br>2:<br>3:<br>4:<br>5:<br>6: 654<br>7:<br>8:<br>9:</p><p>El arreglo se convierte en: 10, 11, 17, 21, 34, 44, 123, 654 que está ordenado. Así es como funciona nuestro algoritmo.</p><p>Una implementación en C:</p><pre><code class="language-c">void countsort(int arr[],int n,int place){

        int i,freq[range]={0};         //el rango de números enteros es 10 ya que los dígitos van del 0 al 9

        int output[n];

        for(i=0;i&lt;n;i++)
                freq[(arr[i]/place)%range]++;

        for(i=1;i&lt;range;i++)
                freq[i]+=freq[i-1];
        
        for(i=n-1;i&gt;=0;i--){
                output[freq[(arr[i]/place)%range]-1]=arr[i];
                freq[(arr[i]/place)%range]--;
        }
        
        for(i=0;i&lt;n;i++)
                arr[i]=output[i];
}

void radixsort(ll arr[],int n,int maxx){            //maxx es el elemento máximo en el arreglo

        int mul=1;
        while(maxx){
                countsort(arr,n,mul);
                mul*=10;
                maxx/=10;
        }
}
</code></pre><h2 id="selection-sort-ordenaci-n-de-selecci-n-"><strong><strong>Selection Sort</strong> (</strong>Ordenación<strong> de selección)</strong></h2><p>Selection Sort es uno de los algoritmos de ordenación más simples. Este algoritmo recibe su nombre de la forma en que itera a través del arreglo: Selecciona el elemento más pequeño actual y lo cambia de lugar.</p><p>Así es como funciona:</p><ol><li>Encuentra el elemento más pequeño en el arreglo y lo intercambia con el primer elemento.</li><li>Encuentra el segundo elemento más pequeño y lo intercambia con el segundo elemento del arreglo.</li><li>Encuentra el tercer elemento más pequeño y lo intercambia con el tercer elemento del arreglo.</li><li>Repite el proceso de encontrar el siguiente elemento más pequeño y cambiarlo a la posición correcta hasta que se ordene todo el arreglo.</li></ol><p>Pero, ¿cómo escribirías el código para encontrar el índice del segundo valor más pequeño en un arreglo?</p><p>Una manera fácil es notar que el valor más pequeño ya se ha cambiado al índice 0, por lo que el problema se reduce a encontrar el elemento más pequeño en el arreglo que comienza en el índice 1.</p><p>La ordenación por selección siempre toma el mismo número de comparaciones clave — N(N − 1)/2.</p><h3 id="implementaci-n-en-c-c-"><strong>Implementación en C/C++</strong></h3><p>El siguiente programa en C++ contiene una implementación iterativa y recursiva del algoritmo de ordenación por selección. Ambas implementaciones se invocan en la función &nbsp;<code>main()</code>.</p><pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;

template&lt;typename T, size_t n&gt;
void print_array(T const(&amp;arr)[n]) {
    for (size_t i = 0; i &lt; n; i++)
        std::cout &lt;&lt; arr[i] &lt;&lt; ' ';
    cout &lt;&lt; "\n";
}

int minIndex(int a[], int i, int j) {
    if (i == j)
        return i;
    int k = minIndex(a, i + 1, j);
    return (a[i] &lt; a[k]) ? i : k;
}

void recurSelectionSort(int a[], int n, int index = 0) {
    if (index == n)
        return;
    int k = minIndex(a, index, n - 1);
    if (k != index)
        swap(a[k], a[index]);
    recurSelectionSort(a, n, index + 1);
}

void iterSelectionSort(int a[], int n) {
    for (int i = 0; i &lt; n; i++)
    {
        int min_index = i;
        int min_element = a[i];
        for (int j = i + 1; j &lt; n; j++)
        {
            if (a[j] &lt; min_element)
            {
                min_element = a[j];
                min_index = j;
            }
        }
        swap(a[i], a[min_index]);
    }
}

int main() {
    int recurArr[6] = { 100,35, 500, 9, 67, 20 };
    int iterArr[5] = { 25, 0, 500, 56, 98 };

    cout &lt;&lt; "Recursive Selection Sort"  &lt;&lt; "\n";
    print_array(recurArr); // 100 35 500 9 67 20
    recurSelectionSort(recurArr, 6);
    print_array(recurArr); // 9 20 35 67 100 500

    cout &lt;&lt; "Iterative Selection Sort" &lt;&lt; "\n";
    print_array(iterArr); // 25 0 500 56 98
    iterSelectionSort(iterArr, 5);
    print_array(iterArr); // 0 25 56 98 500
}
</code></pre><h3 id="implementaci-n-en-javascript-1"><strong>Implementación en JavaScript</strong></h3><pre><code class="language-js">function selection_sort(A) {
    var len = A.length;
    for (var i = 0; i &lt; len - 1; i = i + 1) {
        var j_min = i;
        for (var j = i + 1; j &lt; len; j = j + 1) {
            if (A[j] &lt; A[j_min]) {
                j_min = j;
            } else {}
        }
        if (j_min !== i) {
            swap(A, i, j_min);
        } else {}
    }
}

function swap(A, x, y) {
    var temp = A[x];
    A[x] = A[y];
    A[y] = temp;
}
</code></pre><h3 id="implementaci-n-en-python"><strong>Implementación en Python</strong></h3><pre><code class="language-ps">def seletion_sort(arr):
         if not arr:
         return arr
    for i in range(len(arr)):
         min_i = i
         for j in range(i + 1, len(arr)):
              if arr[j] &lt; arr[min_i]:
                  min_i = j
         arr[i], arr[min_i] = arr[min_i], arr[i]
</code></pre><h3 id="implementaci-n-en-java"><strong>Implementación en Java</strong></h3><pre><code class="language-java">public void selectionsort(int array[])
{
    int n = array.length;            // método para encontrar la longitud del arreglo
    for (int i = 0; i &lt; n-1; i++)
    {
        int index = i;
        int min = array[i];                  // tomando el elemento min como i-ésimo elemento del arreglo
        for (int j = i+1; j &lt; n; j++)
        {
            if (array[j] &lt; array[index])
            {
                index = j;
                min = array[j];
            }
        }
        int t = array[index];         //Intercambiar los lugares de los elementos
        array[index] = array[i];
        array[i] = t;
    }
}
</code></pre><h3 id="implementaci-n-en-matlab"><strong>Implementación en MATLAB</strong></h3><pre><code>function [sorted] = selectionSort(unsorted)
    len = length(unsorted);
    for i = 1:1:len
        minInd = i;
        for j = i+1:1:len
           if unsorted(j) &lt; unsorted(minInd) 
               minInd = j;
           end
        end
        unsorted([i minInd]) = unsorted([minInd i]);    
    end
    sorted = unsorted;
end
</code></pre><h3 id="propiedades-1"><strong>Propiedades</strong></h3><ul><li>Complejidad espacial: &nbsp; <strong><strong>O(n)</strong></strong></li><li>Complejidad del tiempo: &nbsp; <strong><strong>O(n2)</strong></strong></li><li>Ordenación en el lugar: &nbsp; <strong><strong>Sí</strong></strong></li><li>Estable: &nbsp; <strong>No</strong></li></ul><h2 id="bubble-sort-ordenaci-n-de-burbuja-"><strong><strong>Bubble Sort</strong> (Ordenación de burbuja)</strong></h2><p>Al igual que las burbujas se elevan desde el fondo de un vaso, <strong><strong>la </strong>ordenación<strong> de burbujas</strong></strong> es un algoritmo simple que ordena una lista, lo que permite que los valores más bajos o más altos aparezcan en la parte superior. El algoritmo atraviesa una lista y compara valores adyacentes, intercambiandolos si no están en el orden correcto.</p><p>Con una complejidad en el peor de los casos de O(n^2), la ordenación de burbujas es muy lenta en comparación con otros algoritmos de ordenación como la ordenación rápida. La ventaja es que es uno de los algoritmos de ordenación más fáciles de entender y codificar desde cero.</p><p>Desde una perspectiva técnica, la ordenación por burbuja es razonable para ordenar arreglos de tamaño pequeño o especialmente cuando se ejecutan algoritmos de ordenación en ordenadores con recursos de memoria notablemente limitados.</p><h3 id="ejemplo--2"><strong>Ejemplo:</strong></h3><h3 id="primer-paso-por-la-lista-"><strong>Primer paso por la lista:</strong></h3><ul><li>Comenzando con <code>[4, 2, 6, 3, 9]</code>, el algoritmo compara los dos primeros elementos del arreglo, 4 y 2. Los intercambia porque 2 &lt; 4:<code>[2, 4, 6, 3, 9]</code></li><li>Compara los siguientes dos valores, 4 y 6. Como 4 &lt; 6, estos ya están en orden, y el algoritmo continúa:<code>[2, 4, 6, 3, 9]</code></li><li>Los siguientes dos valores también se intercambian porque 3 &lt; 6:<code>[2, 4, 3, 6, 9]</code></li><li>Los dos últimos valores, 6 y 9, ya están en orden, por lo que el algoritmo no los intercambia.</li></ul><h3 id="second-pass-through-the-list-segundo-paso-por-la-lista-"><strong><strong>Second pass through the list:</strong></strong><br><strong>Segundo paso por la lista:</strong></h3><ul><li>2 &lt; 4, por lo que no hay necesidad de intercambiar posiciones:<code>[2, 4, 3, 6, 9]</code></li><li>El algoritmo intercambia los siguientes dos valores porque 3 &lt; 4:<code>[2, 3, 4, 6, 9]</code></li><li>Sin intercambio porque 4 &lt; 6:<code>[2, 3, 4, 6, 9]</code></li><li>De nuevo, 6 &lt; 9, por lo que no se produce intercambio:<code>[2, 3, 4, 6, 9]</code></li></ul><p>La lista ya está ordenada, pero el algoritmo de ordenación de burbujas no se da cuenta de esto. Más bien, necesita completar una pasada completa a través de la lista sin intercambiar ningún valor para saber que la lista está ordenada.</p><h3 id="tercer-paso-por-la-lista-"><strong>Tercer paso por la lista:</strong></h3><ul><li><code>[2, 3, 4, 6, 9]</code> =&gt; <code>[2, 3, 4, 6, 9]</code></li><li><code>[2, 3, 4, 6, 9]</code> =&gt; <code>[2, 3, 4, 6, 9]</code></li><li><code>[2, 3, 4, 6, 9]</code> =&gt; <code>[2, 3, 4, 6, 9]</code></li><li><code>[2, 3, 4, 6, 9]</code> =&gt; <code>[2, 3, 4, 6, 9]</code></li></ul><p>Claramente, la ordenación por burbujas está lejos de ser el algoritmo de ordenación más eficiente. Aún así, es simple entenderlo e implementarlo por ti mismo.</p><h4 id="propiedades-2"><strong>Propiedades</strong></h4><ul><li>Complejidad del espacio: O(1)</li><li>Rendimiento en el mejor caso: O(n)</li><li>Rendimiento promedio de casos: O(n*n)</li><li>Rendimiento en el peor de los casos: O(n*n)</li><li>Estable: Sí</li></ul><h3 id="v-deo-explicaci-n-en-ingl-s-"><strong>Vídeo Explicación (en inglés)</strong></h3><p><a href="https://www.youtube.com/watch?v=Jdtq5uKz-w4">Algoritmo de ordenación de burbujas</a></p><h3 id="ejemplo-en-javascript"><strong>Ejemplo en JavaScript</strong></h3><pre><code class="language-js">let arr = [1, 4, 7, 45, 7,43, 44, 25, 6, 4, 6, 9],
    sorted = false;

while(!sorted) {
  sorted = true;
  for(var i=0; i &lt; arr.length; i++) {
    if(arr[i] &lt; arr[i-1]) {
      let temp = arr[i];
      arr[i] = arr[i-1];
      arr[i-1] = temp;
      sorted = false;
    }
  }
}
</code></pre><h3 id="ejemplo-en-java"><strong>Ejemplo en Java</strong></h3><pre><code class="language-java">public class BubbleSort {
    static void sort(int[] arr) {
        int n = arr.length;
        int temp = 0;
         for(int i=0; i &lt; n; i++){
                 for(int x=1; x &lt; (n-i); x++){
                          if(arr[x-1] &gt; arr[x]){
                                 temp = arr[x-1];
                                 arr[x-1] = arr[x];
                                 arr[x] = temp;
                         }

                 }
         }

    }
    public static void main(String[] args) {

		for(int i=0; i &lt; 15; i++){
			int arr[i] = (int)(Math.random() * 100 + 1);
		}

                System.out.println("array before sorting\n");
                for(int i=0; i &lt; arr.length; i++){
                        System.out.print(arr[i] + " ");
                }
                bubbleSort(arr);
                System.out.println("\n array after sorting\n");
                for(int i=0; i &lt; arr.length; i++){
                        System.out.print(arr[i] + " ");
                }

        }
}
</code></pre><h3 id="ejemplo-en-c-"><strong>Ejemplo en C++</strong></h3><pre><code class="language-cpp">// Implementación recursiva
void bubblesort(int arr[], int n)
{
	if(n==1)	//Initial Case  
//Caso inicial
		return;
	bool swap_flag = false;
	for(int i=0;i&lt;n-1;i++)	//Después de este paso, el elemento más grande se moverá a la ubicación deseada.
	{
		if(arr[i]&gt;arr[i+1])
		{
			int temp=arr[i];
			arr[i]=arr[i+1];
			arr[i+1]=temp;
			swap_flag = true;
		}
	}
               
// SI no se intercambiaron dos elementos en el ciclo, luego regresa, ya que el arreglo está ordenado
	if(swap_flag == false)
		return;
	bubblesort(arr,n-1);	//Recursividad para el arreglo restante
}
</code></pre><h3 id="ejemplo-en-swift"><strong>Ejemplo en Swift</strong></h3><pre><code class="language-swift">func bubbleSort(_ inputArray: [Int]) -&gt; [Int] {
    guard inputArray.count &gt; 1 else { return inputArray } 
    // asegúrandose de que nuestro arreglo de entrada tenga más de 1 elemento
    var numbers = inputArray // los argumentos de la función son constantes por defecto en Swift, así que hacemos una copia
    for i in 0..&lt;(numbers.count - 1) {
        for j in 0..&lt;(numbers.count - i - 1) {
            if numbers[j] &gt; numbers[j + 1] {
                numbers.swapAt(j, j + 1)
            }
        }
    }
    return numbers // devuelve el arreglo ordenado
} 
</code></pre><h3 id="ejemplo-en-python"><strong>Ejemplo en Python</strong></h3><pre><code class="language-py">def bubbleSort(arr): 
    n = len(arr) 
    for i in range(n):
        for j in range(0, n-i-1):
                if arr[j] &gt; arr[j+1] : 
                        arr[j], arr[j+1] = arr[j+1], arr[j]
    print(arr)
</code></pre><h3 id="ejemplo-en-php"><strong>Ejemplo en PHP</strong></h3><pre><code class="language-php">function bubble_sort($arr) {
    $size = count($arr)-1;
    for ($i=0; $i&lt;$size; $i++) {
        for ($j=0; $j&lt;$size-$i; $j++) {
            $k = $j+1;
            if ($arr[$k] &lt; $arr[$j]) {
                // Intercambiar elementos en índices: $j, $k
                list($arr[$j], $arr[$k]) = array($arr[$k], $arr[$j]);
            }
        }
    }
    return $arr; // devuelve el arreglo ordenado
}

$arr = array(1,3,2,8,5,7,4,0);
print("Antes de ordenar");
print_r($arr);

$arr = bubble_sort($arr);
print("Después de ordenar usando ordenación por burbujas");
print_r($arr);
</code></pre><h3 id="ejemplo-en-c"><strong><strong>E</strong>jemplo en C</strong><br></h3><pre><code class="language-c">#include &lt;stdio.h&gt;

int BubbleSort(int array[], int n);

int main(void) {
  int arr[] = {10, 2, 3, 1, 4, 5, 8, 9, 7, 6};
  BubbleSort(arr, 10);

  for (int i = 0; i &lt; 10; i++) {
    printf("%d", arr[i]);
  }
  return 0;
}
int BubbleSort(int array[], n)
{
for (int i = 0 ; i &lt; n - 1; i++)
  {
    for (int j = 0 ; j &lt; n - i - 1; j++)     //n es la longitud del arreglo
    {
      if (array[j] &gt; array[j+1])      // Para uso en orden decreciente
      {
        int swap   = array[j];
        array[j]   = array[j+1];
        array[j+1] = swap;
      }
    }
  }
}
</code></pre><h2 id="ordenaci-n-r-pida"><strong>Ordenación rápida</strong></h2><p>Quick sort es un eficiente algoritmo de ordenación divide y vencerás. La complejidad de tiempo del caso promedio de Quick Sort es O (nlog (n)) y la complejidad de tiempo del peor caso es O (n ^ 2) dependiendo de la selección del elemento pivote, que divide el arreglo actual en dos sub arreglos.</p><p>Por ejemplo, la complejidad de tiempo de Quick Sort es aproximadamente <code>O(nlog(n))</code> cuando la selección del pivote divide el arreglo original en dos subarreglos de tamaño casi igual.</p><p>Por otro lado, si el algoritmo, que selecciona el elemento pivote de los arreglos de entrada, genera consistentemente 2 subarreglos con una gran diferencia en términos de tamaños de arreglo, el algoritmo de ordenación rápida puede lograr la complejidad de tiempo del peor caso de O(n^2 ).</p><p>Los pasos involucrados en Quick Sort son:</p><ul><li>Elige un elemento para que sirva como pivote, en este caso, el último elemento del arreglo es el pivote. </li><li>Particionamiento: Ordena el arreglo de tal manera que todos los elementos menores que el pivote estén a la izquierda y todos los elementos mayores que el pivote estén a la derecha.</li><li>Llama a Quicksort de forma recursiva, teniendo en cuenta el pivote anterior para subdividir adecuadamente los arreglos izquierdo y derecho. (Se puede encontrar una explicación más detallada en los comentarios a continuación)</li></ul><h2 id="implementaciones-de-ejemplo-en-varios-lenguajes"><strong>Implementaciones de ejemplo en varios lenguajes</strong></h2><h3 id="implementaci-n-en-javascript-"><strong>Implementación en JavaScript:</strong></h3><pre><code class="language-js">const arr = [6, 2, 5, 3, 8, 7, 1, 4];

const quickSort = (arr, start, end) =&gt; {

  if(start &lt; end) {

   // Puedes obtener información sobre cómo se deriva el valor de pivote en los comentarios a continuación
    let pivot = partition(arr, start, end);

   // Asegúrate de leer los comentarios a continuación para comprender por qué se usan pivote - 1 y pivote + 1
// Estas son las llamadas recursivas a quickSort
    quickSort(arr, start, pivot - 1);
    quickSort(arr, pivot + 1, end);
  } 

}

const partition = (arr, start, end) =&gt; { 
  let pivot = end;
    // Establece i en start - 1 para que puedas acceder al primer índice en caso de que el valor en arr[0] sea mayor que arr[pivot]
  // Los comentarios posteriores se expondrán sobre el comentario anterior
  let i = start - 1,
      j = start;

  // Incrementa j hasta el índice que precede al pivote
  while (j &lt; pivot) {

    // If the value is greater than the pivot increment j
    // Si el valor es mayor que el pivote incrementa j
    if (arr[j] &gt; arr[pivot]) {
      j++;
    }

    // Cuando el valor en arr[j] es menor que el pivote:
    // incrementa i (arr[i] será un valor mayor que arr[pivot]) e intercambia el valor en arr[i] y arr[j]
    else {
      i++;
      swap(arr, j, i);
      j++;
    }

  }

  //El valor de arr[i + 1] será mayor que el valor de arr[pivot]
  swap(arr, i + 1, pivot);

    //Devuelves i + 1, ya que los valores a la izquierda son menores que arr[i+1], y los valores a la derecha son mayores que arr[i + 1]
   // Como tal, cuando se llama a las ordenaciones rápidas recursivas, los nuevos subconjuntos no incluirán este valor de pivote utilizado anteriormente 
  return i + 1;
}

const swap = (arr, firstIndex, secondIndex) =&gt; {
  let temp = arr[firstIndex];
  arr[firstIndex] = arr[secondIndex];
  arr[secondIndex] = temp;
}

quickSort(arr, 0, arr.length - 1);
console.log(arr);
</code></pre><h3 id="implementaci-n-en-c"><strong>Implementación en C</strong></h3><pre><code class="language-c">#include&lt;stdio.h&gt;  
void swap(int* a, int* b) 
{ 
    int t = *a; 
    *a = *b; 
    *b = t; 
}
int partition (int arr[], int low, int high) 
{ 
    int pivot = arr[high];     
    int i = (low - 1);  
  
    for (int j = low; j &lt;= high- 1; j++) 
    { 
        if (arr[j] &lt;= pivot) 
        { 
            i++;    
            swap(&amp;arr[i], &amp;arr[j]); 
        } 
    } 
    swap(&amp;arr[i + 1], &amp;arr[high]); 
    return (i + 1); 
}
void quickSort(int arr[], int low, int high) 
{ 
    if (low &lt; high) 
    {
        int pi = partition(arr, low, high); 
  
        quickSort(arr, low, pi - 1); 
        quickSort(arr, pi + 1, high); 
    } 
} 
  

void printArray(int arr[], int size) 
{ 
    int i; 
    for (i=0; i &lt; size; i++) 
        printf("%d ", arr[i]); 
    printf("n"); 
} 
  

int main() 
{ 
    int arr[] = {10, 7, 8, 9, 1, 5}; 
    int n = sizeof(arr)/sizeof(arr[0]); 
    quickSort(arr, 0, n-1); 
    printf("Sorted array: n"); 
    printArray(arr, n); 
    return 0; 
} 
</code></pre><h3 id="implementaci-n-en-python3"><strong>Implementación en Python3</strong></h3><pre><code>import random

z=[random.randint(0,100) for i in range(0,20)]

def quicksort(z):
    if(len(z)&gt;1):        
        piv=int(len(z)/2)
        val=z[piv]
        lft=[i for i in z if i&lt;val]
        mid=[i for i in z if i==val]
        rgt=[i for i in z if i&gt;val]

        res=quicksort(lft)+mid+quicksort(rgt)
        return res
    else:
        return z
        
ans1=quicksort(z)
print(ans1)
</code></pre><h3 id="implementaci-n-en-matlab-1"><strong>Implementación en MATLAB </strong></h3><pre><code>a = [9,4,7,3,8,5,1,6,2];

sorted = quicksort(a,1,length(a));

function [unsorted] =  quicksort(unsorted, low, high)
    if low &lt; high
        [pInd, unsorted] = partition(unsorted, low, high);
        unsorted = quicksort(unsorted, low, pInd-1);
        unsorted = quicksort(unsorted, pInd+1, high);
    end

end

function [pInd, unsorted] = partition(unsorted, low, high)
    i = low-1;
    for j = low:1:high-1
        if unsorted(j) &lt;= unsorted(high)
            i = i+1;
            unsorted([i,j]) = unsorted([j,i]);
            
        end
    end
    unsorted([i+1,high]) = unsorted([high,i+1]);
    pInd = i+1;

end
</code></pre><p>La complejidad espacial de ordenación rápida es <code>O(n)</code>. Esta es una mejora con respecto a otros algoritmos de ordenación de divide y vencerás, que ocupan espacio <code>O(nlong(n))</code>.</p><p>La ordenación rápida logra esto cambiando el orden de los elementos dentro del arreglo dado. Compara esto con el algoritmo <a href="https://guide.freecodecamp.org/algorithms/sorting-algorithms/merge-sort">de ordenación por combinación</a> que crea 2 arreglos, cada longitud <code>n/2</code>, en cada llamada de función.</p><p>Sin embargo, existe el problema de que este algoritmo de ordenación es de tiempo <code>O(n*n)</code>si el pivote siempre se mantiene en el medio. Esto se puede superar utilizando un pivote aleatorio.</p><h3 id="complejidad"><strong>Complejidad</strong></h3><p>Mejor, promedio, peor, memoria: n log(n)n log(n)n 2log(n). No es un algoritmo estable, y la ordenación rápida generalmente se realiza en el lugar con el espacio de pila O (log (n)).</p><p>La complejidad espacial de ordenación rápida es O(n). Esta es una mejora con respecto a otros algoritmos de ordenación de divide y vencerás, que ocupan espacio O(n log(n)).</p><h2 id="timsort"><strong>Timsort</strong></h2><p>Timsort es un algoritmo de ordenación rápido que funciona con una complejidad estable de O(N log(N)).</p><p>Timsort es una mezcla de Insertion Sort y Mergesort. Este algoritmo se implementa en Arrays.sort() de Java, así como en sorted() y sort() de Python. Las partes más pequeñas se ordenan mediante Ordenación por inserción y luego se fusionan mediante Mergesort.</p><p>Una implementación rápida en Python:</p><pre><code class="language-py">def binary_search(the_array, item, start, end):
    if start == end:
        if the_array[start] &gt; item:
            return start
        else:
            return start + 1
    if start &gt; end:
        return start

    mid = round((start + end)/ 2)

    if the_array[mid] &lt; item:
        return binary_search(the_array, item, mid + 1, end)

    elif the_array[mid] &gt; item:
        return binary_search(the_array, item, start, mid - 1)

    else:
        return mid

"""
Ordenación por inserción que usa timsort si el tamaño del arreglo es pequeño o si el tamaño de la "carrera" es pequeño
"""
def insertion_sort(the_array):
    l = len(the_array)
    for index in range(1, l):
        value = the_array[index]
        pos = binary_search(the_array, value, 0, index - 1)
        the_array = the_array[:pos] + [value] + the_array[pos:index] + the_array[index+1:]
    return the_array

def merge(left, right):
    """
  Toma dos listas ordenadas y devuelve una sola lista ordenada comparando los
    elementos de uno en uno.
    [1, 2, 3, 4, 5, 6]
    """
    if not left:
        return right
    if not right:
        return left
    if left[0] &lt; right[0]:
        return [left[0]] + merge(left[1:], right)
    return [right[0]] + merge(left, right[1:])

def timsort(the_array):
    runs, sorted_runs = [], []
    length = len(the_array)
    new_run = [the_array[0]]

    # para cada i en el rango de 1 a la longitud del arreglo
    for i in range(1, length):
        # si i está al final de la lista
        if i == length - 1:
            new_run.append(the_array[i])
            runs.append(new_run)
            break
        # si el i-ésimo elemento del arreglo es menor que el anterior
        if the_array[i] &lt; the_array[i-1]:
            # si new_run se establece en Ninguno (NULL)
            if not new_run:
                runs.append([the_array[i]])
                new_run.append(the_array[i])
            else:
                runs.append(new_run)
                new_run = []
        # de lo contrario si es igual o mayor 
        else:
            new_run.append(the_array[i])

    # para cada elemento en las ejecuciones, agrégalo usando la ordenación por inserción
    for item in runs:
        sorted_runs.append(insertion_sort(item))
    
    # por cada ejecución en sorted_runs, fusionarlos

    sorted_array = []
    for run in sorted_runs:
        sorted_array = merge(sorted_array, run)

    print(sorted_array)

timsort([2, 3, 1, 5, 6, 7])
</code></pre><h3 id="complejidad-"><strong>Complejidad:</strong></h3><p>Tim sort tiene una complejidad estable de O(N log(N)) y se compara muy bien con Quicksort. <a href="https://cdn-images-1.medium.com/max/1600/1*1CkG3c4mZGswDShAV9eHbQ.png">En este cuadro</a> se puede encontrar una comparación de complejidades.</p><h2 id="merge-sort-ordenar-por-fusi-n-"><strong><strong>Merge Sort</strong> (Ordenar por fusión)</strong></h2><p>Merge Sort es un algoritmo <a href="https://guide.freecodecamp.org/algorithms/divide-and-conquer-algorithms">Divide y vencerás</a>. Divide el arreglo de entrada en dos mitades, se llama a sí mismo para las dos mitades y luego fusiona las dos mitades ordenadas. La mayor parte del algoritmo tiene dos matrices ordenadas, y tenemos que fusionarlas en un único arreglo ordenado. Todo el proceso de ordenar un arreglo de N enteros se puede resumir en tres pasos:</p><ul><li>Divide el arreglo en dos mitades.</li><li>Ordena la mitad izquierda y la mitad derecha usando el mismo algoritmo recurrente.</li><li>Combina las mitades ordenadas.</li></ul><p>Hay algo conocido como el <a href="https://en.wikipedia.org/wiki/Cheney%27s_algorithm">algoritmo de dos dedos</a> que nos ayuda a fusionar dos arreglos ordenados. El uso de esta subrutina y la llamada a la función de ordenación por fusión en las mitades del arreglo de forma recursiva nos dará el arreglo ordenado final que estamos buscando.</p><p>Dado que este es un algoritmo basado en la recursión, tenemos una relación de recurrencia para él. Una relación de recurrencia es simplemente una forma de representar un problema en términos de sus subproblemas.</p><p><code>T(n) = 2 * T(n / 2) + O(n)</code></p><p>Poniéndolo en lenguaje sencillo, dividimos el subproblema en dos partes en cada paso y tenemos una cantidad lineal de trabajo que tenemos que hacer para unir las dos mitades ordenadas en cada paso.</p><h3 id="complejidad-1"><strong>Complejidad</strong></h3><p>La mayor ventaja de usar Merge sort es que la <a href="https://www.youtube.com/watch?v=V42FBiohc6c&amp;list=PL2_aWCzGMAwI9HK8YPVBjElbLbI3ufctn" rel="nofollow">complejidad del tiempo</a> es solo n*log(n) para ordenar un Array completo. Es mucho mejor que n ^ 2 tiempo de ejecución de ordenación de burbuja o ordenación de inserción.</p><p>Antes de escribir el código, comprendamos cómo funciona la ordenación por combinación o fusión con la ayuda de un diagrama.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/06/4712ef1a5d856dbb4af393fcc08a820a38787395.png" class="kg-image" alt="4712ef1a5d856dbb4af393fcc08a820a38787395" width="600" height="400" loading="lazy"></figure><ul><li>Inicialmente tenemos un arreglo de 6 enteros no ordenados Arr(5, 8, 3, 9, 1, 2) </li><li>Dividimos el arreglo en dos mitades Arr1 = (5, 8, 3) y Arr2 = (9, 1, 2).</li><li>De nuevo, los dividimos en dos mitades: Arr3 = (5, 8) and Arr4 = (3) and Arr5 = (9, 1) and Arr6 = (2)</li><li>De nuevo, los dividimos en dos mitades: Arr7 = (5), Arr8 = (8), Arr9 = (9), Arr10 = (1) y Arr6 = (2)</li><li>Ahora compararemos los elementos en estos subconjuntos para fusionarlos.</li></ul><h3 id="propiedades--1"><strong>Propiedades:</strong></h3><ul><li>Complejidad espacial: O(n)</li><li>Complejidad temporal: O(n*log(n)). La complejidad del tiempo para Merge Sort podría no ser obvia a primera vista. El factor log(n) que entra se debe a la relación de recurrencia que hemos mencionado antes.</li><li>Ordenar en el lugar: No en una implementación típica</li><li>Estable: Sí</li><li>Paralelizable: sí (varias variantes paralelas se analizan en la tercera edición de Introducción a los algoritmos de Cormen, Leiserson, Rivest y Stein).</li></ul><h3 id="implementaci-n-de-c--1"><strong><strong><strong>I</strong></strong>m<strong><strong>ple</strong></strong>m<strong><strong>entación de C++</strong></strong></strong></h3><pre><code class="language-cpp">void merge(int array[], int left, int mid, int right)
{
    int i, j, k;

    // Tamaño de la sublista izquierda
int size_left = mid - left + 1;

// Tamaño de la sublista derecha
int size_right =  right - mid;

/* crea arreglos temporales */
int Left[size_left], Right[size_right];

/* Copiar datos a arreglos temporales L[] y R[] */
for(i = 0; i &lt; size_left; i++)
{
    Left[i] = array[left+i];
}

for(j = 0; j &lt; size_right; j++)
{
    Right[j] = array[mid+1+j];
}

// Combinar los arreglos temporales de nuevo en arr[left..right]
i = 0; // Índice inicial del subarreglo izquierdo
j = 0; // Índice inicial del subarreglo derecho
k = left; // Índice inicial del subarreglo fusionado

while (i &lt; size_left &amp;&amp; j &lt; size_right)
{
    if (Left[i] &lt;= Right[j])
    {
        array[k] = Left[i];
        i++;
    }
    else
    {
        array[k] = Right[j];
        j++;
    }
    k++;
}

// Copia los elementos restantes de Left[]
while (i &lt; size_left)
{
    array[k] = Left[i];
    i++;
    k++;
}

// Copiar el resto de elementos de Right[]
while (j &lt; size_right)
{
    array[k] = Right[j];
    j++;
    k++;
}
}

void mergeSort(int array[], int left, int right)
{
    if(left &lt; right)
    {
        int mid = (left+right)/2;

        // Ordenar la primera y la segunda mitad
    mergeSort(array, left, mid);
    mergeSort(array, mid+1, right);

    // Finalmente fusionarlas
    merge(array, left, mid, right);
}
}</code></pre><h3 id="implementaci-n-de-javascript"><strong><strong><strong>Implementación de JavaScript</strong></strong></strong></h3><pre><code class="language-js">function mergeSort (arr) {
  if (arr.length &lt; 2) return arr;
  var mid = Math.floor(arr.length /2);
  var subLeft = mergeSort(arr.slice(0,mid));
  var subRight = mergeSort(arr.slice(mid));
  return merge(subLeft, subRight);
}</code></pre><p>Primero verificamos la longitud del arreglo. Si es 1, simplemente devolvemos el arreglo. Este sería nuestro caso base. De lo contrario, encontraremos el valor medio y dividiremos el arreglo en dos mitades. Ahora ordenaremos ambas mitades con llamadas recursivas a la función MergeSort.</p><pre><code class="language-js">function merge (a,b) {
    var result = [];
    while (a.length &gt;0 &amp;&amp; b.length &gt;0)
        result.push(a[0] &lt; b[0]? a.shift() : b.shift());
    return result.concat(a.length? a : b);
}</code></pre><p>Cuando fusionamos las dos mitades, almacenamos el resultado en un arreglo auxiliar. Compararemos el elemento inicial del arreglo izquierdo con el elemento inicial del arreglo derecho. Cualquiera que sea menor se insertará en el arreglo de resultados y lo eliminaremos de los arreglos respectivos usando el operador [shift()]. Si aún terminamos con valores en el arreglo izquierdo o derecho, simplemente los concatenaremos al final del resultado. Aquí está el resultado ordenado:</p><pre><code class="language-js">var test = [5,6,7,3,1,3,15];
console.log(mergeSort(test));

&gt;&gt; [1, 3, 3, 5, 6, 7, 15]</code></pre><h3 id="un-tutorial-de-youtube-de-ordenaci-n-por-combinaci-n"><strong>Un tutorial de YouTube de ordenación por combinación</strong></h3><p>Aquí hay un buen video de YouTube que <a href="https://www.youtube.com/watch?v=TzeBrDU-JaY">explica el tema en detalle</a> .</p><h3 id="implementaci-n-en-js"><strong>Implementación en JS</strong></h3><pre><code class="language-js">const list = [23, 4, 42, 15, 16, 8, 3]

const mergeSort = (list) =&gt;{
  if(list.length &lt;= 1) return list;
  const middle = list.length / 2 ;
  const left = list.slice(0, middle);
  const right = list.slice(middle, list.length);
  return merge(mergeSort(left), mergeSort(right));
}

const merge = (left, right) =&gt; {
  var result = [];
  while(left.length || right.length) {
    if(left.length &amp;&amp; right.length) {
      if(left[0] &lt; right[0]) {
        result.push(left.shift())
      } else {
        result.push(right.shift())
      }
    } else if(left.length) {
        result.push(left.shift())
      } else {
        result.push(right.shift())
      }
    }
  return result;
}

console.log(mergeSort(list)) // [ 3, 4, 8, 15, 16, 23, 42 ]
</code></pre><h3 id="implementaci-n-en-c-1"><strong>Implementación en C</strong></h3><pre><code class="language-c">#include&lt;stdlib.h&gt; 
#include&lt;stdio.h&gt;
void merge(int arr[], int l, int m, int r) 
{ 
    int i, j, k; 
    int n1 = m - l + 1; 
    int n2 =  r - m; 
  
    
    int L[n1], R[n2]; 
  
    for (i = 0; i &lt; n1; i++) 
        L[i] = arr[l + i]; 
    for (j = 0; j &lt; n2; j++) 
        R[j] = arr[m + 1+ j];
    i = 0; 
    j = 0; 
    k = l; 
    while (i &lt; n1 &amp;&amp; j &lt; n2) 
    { 
        if (L[i] &lt;= R[j]) 
        { 
            arr[k] = L[i]; 
            i++; 
        } 
        else
        { 
            arr[k] = R[j]; 
            j++; 
        } 
        k++; 
    } 
  
    
    while (i &lt; n1) 
    { 
        arr[k] = L[i]; 
        i++; 
        k++; 
    } 
  
    while (j &lt; n2) 
    { 
        arr[k] = R[j]; 
        j++; 
        k++; 
    } 
} 
  
void mergeSort(int arr[], int l, int r) 
{ 
    if (l &lt; r) 
    {  
        int m = l+(r-l)/2; 
  
        
        mergeSort(arr, l, m); 
        mergeSort(arr, m+1, r); 
  
        merge(arr, l, m, r); 
    } 
}
void printArray(int A[], int size) 
{ 
    int i; 
    for (i=0; i &lt; size; i++) 
        printf("%d ", A[i]); 
    printf("\n"); 
} 
int main() 
{ 
    int arr[] = {12, 11, 13, 5, 6, 7}; 
    int arr_size = sizeof(arr)/sizeof(arr[0]); 
  
    printf("Given array is \n"); 
    printArray(arr, arr_size); 
  
    mergeSort(arr, 0, arr_size - 1); 
  
    printf("\nSorted array is \n"); 
    printArray(arr, arr_size); 
    return 0; 
</code></pre><h3 id="implementaci-n-en-c-"><strong>Implementación en C++</strong></h3><p>Consideremos el arreglo A = {2,5,7,8,9,12,13} y el arreglo B = {3,5,6,9,15} y queremos que el arreglo C también esté en orden ascendente.</p><pre><code class="language-cpp">void mergesort(int A[],int size_a,int B[],int size_b,int C[])
{
     int token_a,token_b,token_c;
     for(token_a=0, token_b=0, token_c=0; token_a&lt;size_a &amp;&amp; token_b&lt;size_b; )
     {
          if(A[token_a]&lt;=B[token_b])
               C[token_c++]=A[token_a++];
          else
               C[token_c++]=B[token_b++];
      }
      
      if(token_a&lt;size_a)
      {
          while(token_a&lt;size_a)
               C[token_c++]=A[token_a++];
      }
      else
      {
          while(token_b&lt;size_b)
               C[token_c++]=B[token_b++];
      }

}
</code></pre><h3 id="implementaci-n-en-python-1"><strong>Implementación en Python</strong></h3><pre><code class="language-py">def merge(left,right,compare):
	result = [] 
	i,j = 0,0
	while (i &lt; len(left) and j &lt; len(right)):
		if compare(left[i],right[j]):
			result.append(left[i])
			i += 1
		else:
			result.append(right[j])
			j += 1
	while (i &lt; len(left)):
		result.append(left[i])
		i += 1
	while (j &lt; len(right)):
		result.append(right[j])
		j += 1
	return result

def merge_sort(arr, compare = lambda x, y: x &lt; y):
    #Utilizando la función lambda para ordenar el arreglo en orden (creciente y decreciente).
     #Por defecto ordena el arreglo en orden creciente
	if len(arr) &lt; 2:
		return arr[:]
	else:
		middle = len(arr) // 2
		left = merge_sort(arr[:middle], compare)
		right = merge_sort(arr[middle:], compare)
		return merge(left, right, compare) 

arr = [2,1,4,5,3]
print(merge_sort(arr))
</code></pre><h3 id="implementaci-n-en-java-1"><strong>Implementación en Java</strong></h3><pre><code class="language-java">public class mergesort {

	public static int[] mergesort(int[] arr,int lo,int hi) {
		
		if(lo==hi) {
			int[] ba=new int[1];
			ba[0]=arr[lo];
			return ba;
		}
		
		int mid=(lo+hi)/2;
		int arr1[]=mergesort(arr,lo,mid);
		int arr2[]=mergesort(arr,mid+1,hi);
		return merge(arr1,arr2);
	}
	
	public static int[] merge(int[] arr1,int[] arr2) {
		int i=0,j=0,k=0;
		int n=arr1.length;
		int m=arr2.length;
		int[] arr3=new int[m+n];
		while(i&lt;n &amp;&amp; j&lt;m) {
			if(arr1[i]&lt;arr2[j]) {
				arr3[k]=arr1[i];
				i++;
			}
			else {
				arr3[k]=arr2[j];
				j++;
			}
			k++;
		}
		
		while(i&lt;n) {
			arr3[k]=arr1[i];
			i++;
			k++;
		}
		
		while(j&lt;m) {
			arr3[k]=arr2[j];
			j++;
			k++;
		}
		
		return arr3;
		
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int arr[]= {2,9,8,3,6,4,10,7};
		int[] so=mergesort(arr,0,arr.length-1);
		for(int i=0;i&lt;arr.length;i++)
			System.out.print(so[i]+" ");
	}

}
</code></pre><h3 id="ejemplo-en-java-1"><strong>Ejemplo en Java</strong></h3><pre><code class="language-java">public class mergesort {
  public static int[] mergesort(int[] arr, int lo, int hi) {
    if (lo == hi) {
      int[] ba = new int[1];
      ba[0] = arr[lo];
      return ba;
    }
    int mid = (lo + hi) / 2;
    int arr1[] = mergesort(arr, lo, mid);
    int arr2[] = mergesort(arr, mid + 1, hi);
    return merge(arr1, arr2);
  }

  public static int[] merge(int[] arr1, int[] arr2) {
    int i = 0, j = 0, k = 0;
    int n = arr1.length;
    int m = arr2.length;
    int[] arr3 = new int[m + n];
    while (i &lt; n &amp;&amp; j &lt; m) {
      if (arr1[i] &lt; arr2[j]) {
        arr3[k] = arr1[i];
        i++;
      } else {
        arr3[k] = arr2[j];
        j++;
      }
      k++;
    }
    while (i &lt; n) {
      arr3[k] = arr1[i];
      i++;
      k++;
    }
    while (j &lt; m) {
      arr3[k] = arr2[j];
      j++;
      k++;
    }
    return arr3;
  }

  public static void main(String[] args) {
    int arr[] = {2, 9, 8, 3, 6, 4, 10, 7};
    int[] so = mergesort(arr, 0, arr.length - 1);
    for (int i = 0; i &lt; arr.length; i++)
      System.out.print(so[i] + " ");
  }
}
</code></pre> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ La mejor manera de aprender desarrollo web backend ]]>
                </title>
                <description>
                    <![CDATA[ Mi artículo anterior describía cómo puedes entrar en el desarrollo frontend [https://www.freecodecamp.org/news/learn-frontend-web-development/] . También se discutió cómo el front-end puede ser un lugar lleno de minas terrestres: pisa el lugar equivocado y te verás abrumado por los muchos marcos de trabajo (frameworks) del ecosistema de JavaScript. En este artículo, vamos ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/aprender-desarrollo-backend/</link>
                <guid isPermaLink="false">64451f322ef44808032fa4aa</guid>
                
                    <category>
                        <![CDATA[ Desarrollo Backend ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Thu, 27 Apr 2023 20:56:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/04/5f9c9bab740569d1a4ca2d39.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/learn-backend-development/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Best Way to Learn Backend Web Development</a>
      </p><p>Mi artículo anterior describía <a href="https://www.freecodecamp.org/news/learn-frontend-web-development/">cómo puedes entrar en el desarrollo frontend</a> . También se discutió cómo el front-end puede ser un lugar lleno de minas terrestres: pisa el lugar equivocado y te verás abrumado por los muchos marcos de trabajo (frameworks) del ecosistema de JavaScript.</p><p>En este artículo, vamos a ver cómo puedes ingresar al desarrollo de back-end. En el camino, responderé algunas de las preguntas más comunes que la gente me hace al respecto.</p><h2 id="-qu-es-el-desarrollo-back-end"><strong>¿Qué es el desarrollo back-end?</strong></h2><p>El desarrollo front-end implica lo que un usuario ve en la pantalla cuando abre una URL específica de tu propiedad. Incluso en un entorno completamente estático (solo con HTML/CSS), cuando alguien abre un sitio web, algún servidor en el planeta necesita responderle con esos archivos HTML y CSS.</p><p>Ese servidor es solo un ordenador, como el que usas para navegar por Internet. Pero se ha ajustado para el rendimiento y no tiene componentes innecesarios como un mouse o un teclado adjuntos. Y se encuentra con toneladas de otros ordenadores, probablemente en un almacén de datos.</p><p>La programación de esos ordenadores de alguna manera especial se llama <strong><strong>desarrollo de back-end</strong></strong> .</p><p>Puedes pensar que el desarrollo de back-end se llama así porque se ejecuta a espaldas del usuario. Un visitante de tu sitio web nunca "accede" completamente al back-end. Simplemente se comunican con tu servidor, ya sea directamente a través de puertos para un acceso muy limitado (como la transferencia de archivos HTML/CSS) o ni siquiera eso, enterrados profundamente bajo CDN o firewalls (como Cloudflare).</p><p>Ahora que tenemos una comprensión básica de lo que significa el desarrollo de back-end, analicemos algunas preguntas <strong><strong>reales .</strong></strong></p><h2 id="-se-requieren-conocimientos-de-programaci-n-front-end-para-el-back-end"><strong>¿Se requieren conocimientos de programación front-end para el back-end?</strong></h2><p><strong><strong>TLDR;</strong></strong> No. (Too Long; Didn't read | Demasiado largo; no lo leí)</p><p>El desarrollo de back-end, como se mencionó anteriormente, implica la programación de un ordenador ubicado probablemente en el otro lado del planeta responsable de responder a lo que sus usuarios dicen desde sus propios ordenadores.</p><p>Si eres un desarrollador back-end a tiempo completo, realmente no necesitas preocuparte por lo que sucede dentro de esos archivos HTML, CSS y JavaScript que envías al navegador del usuario. En su lugar, debes centrarte más en el rendimiento y el código del servidor.</p><h2 id="-qu-implica-el-desarrollo-de-back-end"><strong>¿Qué implica el desarrollo de back-end?</strong></h2><p>Bueno, siguiendo los libros, puedes decir que una persona que codifica una aplicación que puede responder a solicitudes HTTP es un desarrollador de back-end.</p><p>Pero en realidad, a veces los desarrolladores de back-end pueden hacer mucho más que simplemente escribir scripts de servidor. Tienen el conocimiento para configurar servidores proxy inversos (NGiNX/HAProxy), habilitar la compresión y otras formas de acelerar el sitio, y configurar un entorno contenedor (docker) de producción.</p><p>Para calificar como desarrollador back-end, diría que las habilidades mínimas que necesitas son:</p><ol><li>Buen conocimiento sobre un lenguaje de programación en el que puedes escribir servidores HTTP. Ejemplos: C#, Java, Node, PHP, Python, etc. (¡hay muchos!)</li><li>Administrar para hospedar usando cPanel (tradicional) o usando terminal bash (alojamiento en la nube/tradicional)</li><li>Trabajar con sistemas de control de versiones (VCS) como git para administrar e implementar compilaciones</li></ol><p>Al igual que todos los juegos vienen con especificaciones mínimas y recomendadas, para los desarrolladores de back-end, mis especificaciones recomendadas serían (incluidas las habilidades mínimas):</p><ol><li>NGiNX para activos de archivos estáticos y administración de servidores</li><li>Habilidades de gestión de bases de datos (SQL/NoSQL)</li><li>Seguridad de backend (Escribir código seguro y robusto, ejecutar aplicaciones en contenedores docker con privilegios limitados, protección contra ataques DoS)</li><li>Autoescalado/balanceo de carga</li></ol><p>De acuerdo, demasiada charla sobre lo que sucede en el desarrollo de back-end. Pero, ¿cómo te conviertes en uno?</p><h2 id="comienza-con-los-requisitos-m-nimos"><strong>Comienza con los requisitos mínimos</strong></h2><p>Como dije, para el back-end, al igual que los juegos, tenemos un conjunto de requisitos mínimos y requisitos recomendados. Los requisitos mínimos consisten en 3 cosas:</p><h3 id="aprender-un-lenguaje-de-programaci-n-backend"><strong>Aprender un lenguaje de programación backend</strong></h3><p>Cuando las personas aprenden por sí mismas, por lo general no tienen un equipo ni nadie que pueda desarrollar el front-end. Están totalmente solos. Por lo tanto, a menudo tendrás que crear páginas web y servidores tú mismo, al menos al principio.</p><p>Aunque hay muchas opciones para los lenguajes de programación de back-end, y no puedo pensar en ningún lenguaje de sistema popular que no admita servidores HTTP listos para usar. La ventaja de elegir Node es que sus habilidades de &nbsp;front-end JavaScript son transferibles al back-end.</p><p>No obstante, puedes elegir entre una variedad de lenguajes como Java, C++, C#, Python, PHP, etc.</p><p>¿Cómo elijo uno?, podrías preguntar. La respuesta es la misma que en el artículo de desarrollo front-end: tienes que probar todo inicialmente y ver cuál encaja mejor contigo.</p><p>Node es fácil, ya que es posible que ya hayas realizado la programación JS para el front-end. Pero si eres un desarrollador de Python o Java, es posible que los encuentre fáciles de aprender. Depende completamente de tu profesión y gusto.</p><h3 id="m-s-informaci-n-sobre-la-gesti-n-del-alojamiento"><strong>Más información sobre la gestión del alojamiento</strong></h3><p>Atrás quedaron los días en los que tendrías que comprar servidores manualmente y configurarlos en tu casa, conectarte a tu ISP, hacerlo todo tú mismo. Esta es la era de la computación en la nube. Ahora, al alojar tu sitio web, tienes principalmente 2 opciones:</p><ol><li>Optar por servidores de alojamiento administrados como HostGator o GoDaddy.</li><li>Optar por proveedores de alojamiento en la nube como GCP, AWS o DigitalOcean.</li></ol><p>¿Cuál es la diferencia entre los dos? En ambos casos, los servidores son propiedad y están operados por las respectivas empresas. Pero la principal diferencia es que el alojamiento administrado es más amigable con la GUI, tiene un amplio conjunto de herramientas para ver el sistema de archivos, monitorear el uso, administrar los correos electrónicos de tu dominio oficial, cargar/descargar archivos de tu servidor, etc. Es básicamente una configuración para personas con menos habilidades técnicas.</p><p>Por esa razón, no recomiendo sitios administrados como HostGator o GoDaddy para desarrolladores experimentados. Aún así, podrían ser una buena plataforma para cometer errores y aprender, principalmente porque generalmente tienen planes de prepago para ello. También tendrás una buena interfaz de usuario para administrar las cosas, lo que te permite que no se disparen accidentalmente tus facturas.</p><p>Pero cuando empieces a ganar velocidad, te recomiendo que cambies a un proveedor de nube. Esto elimina todas las buenas herramientas de cPanel que usaste para administrar archivos y carpetas en los servidores. Pero al mismo tiempo, te desafiará a subir mucho de nivel tus habilidades.</p><p>Hoy en día, muchos proveedores de la nube también ofrecen una prueba gratuita decente, para que puedas probar su plataforma antes de entrar por completo. Yo alojo mi sitio web para desarrolladores en DigitalOcean y encuentro que tiene un dulce equilibrio de complejidad y características del sitio.</p><p>Puedes usar <a href="https://m.do.co/c/2c4c3ec5405a">este enlace para registrarte</a> en DigitalOcean y obtener un <strong>crédito de 100 dólares &nbsp;gratis</strong> . Las instancias de DigitalOcean son baratas, &nbsp;como unos 5 dólares por mes, por lo que tienes crédito aproximadamente para 20 meses, gran oferta, ¿no?</p><p>De todos modos, puedes elegir cualquier proveedor de nube. Entonces, es importante aprender a administrar el servidor usando solo la línea de comandos ingresando por ssh en él.</p><h3 id="m-s-informaci-n-sobre-los-sistemas-de-control-de-versiones"><strong>Más información sobre los sistemas de control de versiones</strong></h3><p>Hay otras soluciones además de Git como VCS (Sistema de Control de Versiones por sus siglas en inglés). Pero Git es el más usado y el más simple de entender.</p><p>Como individuo, es posible que no lo aprecies de inmediato. Pero comprenderás por qué es tan importante en el momento en que comiences a trabajar en equipo en varias funciones simultáneamente en tu proyecto.</p><p>Git te permite administrar tu flujo de trabajo usando confirmaciones y ramas. Las confirmaciones son como <strong><strong>puntos de control</strong></strong> en tu código base, a los que siempre puedes volver si cometes un error.</p><p>Las ramas (branches) son como <strong><strong>realidades alternativas</strong></strong> de tu proyecto, donde algo completamente diferente podría suceder. Estas realidades alternativas se pueden crear desde cualquier momento y se pueden fusionar nuevamente en cualquier momento.</p><p>Si esas realidades se pueden fusionar con compatibilidad, entonces está bien. Pero si hay un conflicto (como si estuvieras vivo en una realidad y muerto en otra), entonces tienes que hacer una elección manualmente. Otros cambios se pueden fusionar automáticamente.</p><p>Git es súper interesante, y una vez que lo domines, querrás usarlo en cada proyecto. Puedes mantener un historial de tu trabajo de manera eficiente (git comprime y almacena solo la diferencia entre confirmaciones).</p><p>También te permite crear repositorios git en línea en sitios como GitHub, que actúa como una fuente central de información para tu sitio web. Los sitios como GitHub se pueden configurar con webhooks especiales que realmente pueden actualizar tu sitio web cada vez que agregas un nuevo punto de control (una nueva confirmación) sin necesidad de ir manualmente al servidor y actualizarlo tu mismo.</p><h2 id="ir-a-las-habilidades-recomendadas"><strong>Ir a las habilidades recomendadas</strong></h2><p>Soy un gran creyente en aprender haciendo. Y la mejor manera de hacer algo surge de la necesidad o el interés. Una vez que te consideres lo suficientemente bueno con los requisitos mínimos, es hora de adquirir las habilidades recomendadas. Esto incluye todas las herramientas como Docker y NGiNX mencionadas anteriormente.</p><p><strong><strong>DevOps</strong></strong> también es algo que encaja muy bien con los desarrolladores de back-end. Puedes probar y explorar <strong><strong>TravisCI</strong></strong> o <strong><strong>CircleCI</strong></strong> para implementaciones de compilación automatizadas. La integración e implementación continuas (CI/CD) es un tema que podría ocupar otra publicación de blog completa, por lo que no entraré en eso.</p><p>Luego vienen las bases de datos, que coloqué en habilidades recomendadas. Pero vas a necesitar bases de datos para prácticamente cualquier aplicación que implique algún tipo de persistencia de datos generados por el usuario.</p><p>Las bases de datos suelen ser fáciles para empezar a trabajar, pero más difíciles de mantener y ajustar correctamente. La mejor manera de comenzar a trabajar en una pila tecnológica de back-end es tener todo junto en un solo servidor: el código de tu aplicación, los servidores proxy inversos, la base de datos, etc. Luego, a medida que te vuelves más competente en cada cosa, puedes desacoplarlo de la lógica empresarial existente.</p><p>Al hacer esto, estás habilitando una arquitectura que se puede escalar mucho. Una aplicación intensiva de operación de base de datos podría tener una solución optimizada para bases de datos. Y un sitio con mucho tráfico debe tener un buen mecanismo de CDN para descargar activos estáticos, etc.</p><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>Hay mucho que aprender, pero todo se puede lograr si no te rindes. Déjame saber lo que piensas sobre esta publicación a través de mis cuentas <a href="https://twitter.com/mehulmpt"><strong><strong>de Twitter</strong></strong></a> e <a href="https://instagram.com/mehulmpt"><strong><strong>Instagram</strong></strong></a> . ¡Significará mucho para mí si nos conectamos allí!</p><p>Además, si estás interesado, consulta <a href="https://codedamn.com/"><strong><strong>codedamn</strong></strong></a> , una plataforma centrada en el desarrollador para tecnologías de aprendizaje como el desarrollo de back-end. ¡Incluso publiqué un <a href="https://www.youtube.com/watch?v=IOTL7RqUZEU">video de YT sobre cómo hacer funcionar tu propio servidor web simple en 2 minutos</a> ! ¡Miralo y déjame saber lo que piensas!</p><p>¡Paz!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo crear tu propia criptomoneda usando Python ]]>
                </title>
                <description>
                    <![CDATA[ > Con el auge actual de las criptomonedas, blockchain está creando un gran revuelo en el mundo de la tecnología. Esta tecnología ha atraído tanta atención principalmente por su capacidad para garantizar la seguridad, hacer cumplir la descentralización y acelerar los procesos en varias industrias, especialmente en la industria financiera. ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-crear-tu-propia-criptomoneda-usando-python/</link>
                <guid isPermaLink="false">644099882ef44808032f9eb1</guid>
                
                    <category>
                        <![CDATA[ criptomoneda ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Thu, 27 Apr 2023 18:12:38 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/04/blockchain-3448502_1920-2.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/create-cryptocurrency-using-python/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Create Your Own Cryptocurrency Using Python</a>
      </p><blockquote>Con el auge actual de las criptomonedas, blockchain está creando un gran revuelo en el mundo de la tecnología. Esta tecnología ha atraído tanta atención principalmente por su capacidad para garantizar la seguridad, hacer cumplir la descentralización y acelerar los procesos en varias industrias, especialmente en la industria financiera.</blockquote><p>Esencialmente, una cadena de bloques (blockchain) es una base de datos pública que documenta y auténtica irreversiblemente la posesión y transmisión de activos digitales. Las monedas digitales, como Bitcoin y Ethereum, se basan en este concepto. Blockchain es una tecnología emocionante que puedes utilizar para transformar las capacidades de tus aplicaciones.</p><p>Últimamente, hemos visto gobiernos, organizaciones e individuos que utilizan la tecnología blockchain para crear sus propias criptomonedas y evitar quedarse atrás. En particular, cuando Facebook propuso su propia criptomoneda, llamada Libra, el anuncio agitó muchas aguas en todo el mundo.</p><p>¿Qué pasaría si también pudieras hacer lo mismo y crear tu propia versión de una criptomoneda?</p><p>Pensé en esto y decidí desarrollar un algoritmo que crea una criptografía.</p><p>Decidí llamar a la criptomoneda <strong><strong>fccCoin</strong></strong>.</p><p>En este tutorial, voy a ilustrar el proceso paso a paso que utilicé para crear la moneda digital (utilicé los conceptos orientados a objetos del lenguaje de programación <a href="https://www.freecodecamp.org/espanol/news/los-mejores-tutoriales-de-python/">Python</a>).</p><p>Este es el modelo básico del algoritmo de cadena de bloques para crear <strong><strong>fccCoin</strong></strong>:</p><pre><code class="language-python">class Block:

    def __init__():

    #primera clase bloque

        pass
    
    def calculate_hash():
    
    #calcula el hash criptográfico de cada bloque    
    
class BlockChain:
    
    def __init__(self):
     # método constructor
    pass
    
    def construct_genesis(self):
        # construye el bloque inicial
        pass

    def construct_block(self, proof_no, prev_hash):
        # construye un nuevo bloque y lo agrega a la cadena
        pass

    @staticmethod
    def check_validity():
        # comprueba si la cadena de bloques es válida
        pass

    def new_data(self, sender, recipient, quantity):
        # agrega una nueva transacción a los datos de las transacciones
        pass

    @staticmethod
    def construct_proof_of_work(prev_proof):
        # protege la cadena de bloques de ataques
        pass
   
    @property
    def last_block(self):
        # devuelve el último bloque de la cadena
        return self.chain[-1]

</code></pre><p>Ahora, déjame explicarte lo que está sucediendo...</p><h2 id="1-construyendo-la-primera-clase-block"><strong>1. Construyendo la primera clase Block</strong></h2><p>Una cadena de bloques se compone de varios bloques que se unen entre sí (eso suena familiar, ¿verdad?).</p><p>El encadenamiento de bloques se lleva a cabo de tal manera que si se manipula un bloque, el resto de la cadena se vuelve inválido.</p><p>Al aplicar el concepto anterior, creé la siguiente clase Block inicial:</p><pre><code class="language-python">import hashlib
import time

class Block:

    def __init__(self, index, proof_no, prev_hash, data, timestamp=None):
        self.index = index
        self.proof_no = proof_no
        self.prev_hash = prev_hash
        self.data = data
        self.timestamp = timestamp or time.time()

    @property
    def calculate_hash(self):
        block_of_string = "{}{}{}{}{}".format(self.index, self.proof_no,
                                              self.prev_hash, self.data,
                                              self.timestamp)

        return hashlib.sha256(block_of_string.encode()).hexdigest()

    def __repr__(self):
        return "{} - {} - {} - {} - {}".format(self.index, self.proof_no,
                                               self.prev_hash, self.data,
                                               self.timestamp)
</code></pre><p><br>Como puedes ver en el código anterior, definí la función <strong><strong>__init__()</strong></strong>, que se ejecutará cuando se inicie la clase <strong><strong>Block</strong></strong>, como en cualquier otra clase de Python.</p><p>Proporcioné los siguientes parámetros a la función de iniciación:</p><ul><li><strong><strong>self</strong></strong>—se refiere a la instancia de la clase <strong><strong>Block</strong></strong>, que permite acceder a los métodos y atributos asociados a la clase;</li><li><strong>index</strong>—realiza un seguimiento de la posición del bloque dentro de la cadena de bloques;</li><li><strong><strong>proof_no</strong></strong>—este es el número producido durante la creación de un nuevo bloque (llamado minería);</li><li><strong><strong>prev_hash</strong></strong>—se refiere al hash del bloque anterior dentro de la cadena;</li><li><strong><strong>dat</strong>a</strong>—esto brinda un registro de todas las transacciones completadas, como la cantidad comprada;</li><li><strong><strong>timestamp</strong></strong>—esto coloca una marca de tiempo para las transacciones.</li></ul><p>El segundo método de la clase, <strong>calculate<strong>_hash</strong></strong>, generará el hash de los bloques utilizando los valores anteriores. El módulo SHA-256 se importa al proyecto para ayudar a obtener los hash de los bloques.</p><p>Una vez que los valores se hayan ingresado en el algoritmo hash criptográfico, la función devolverá una cadena de 256 bits que representa el contenido del bloque.</p><p>Así es como se logra la seguridad en las cadenas de bloques: cada bloque tendrá un hash y ese hash se basará en el hash del bloque anterior.</p><p>Como tal, si alguien intenta comprometer cualquier bloque de la cadena, los otros bloques tendrán hashes no válidos, lo que provocará la interrupción de toda la red de la cadena de bloques.</p><p>En última instancia, un bloque se verá así:</p><pre><code class="language-python">{
    "index": 2,
    "proof": 21,
    "prev_hash": "6e27587e8a27d6fe376d4fd9b4edc96c8890346579e5cbf558252b24a8257823",
    "transactions": [
        {'sender': '0', 'recipient': 'Quincy Larson', 'quantity': 1}
    ],
    "timestamp": 1521646442.4096143
}
</code></pre><h2 id="2-construyendo-la-clase-blockchain"><strong>2. Construyendo la clase Blockchain</strong></h2><p>La idea principal de una cadena de bloques, tal como su nombre lo indica, consiste en "encadenar" varios bloques entre sí.</p><p>Por lo tanto, voy a construir una clase <strong><strong>Blockchain</strong></strong> que será útil para administrar el funcionamiento de toda la cadena. Aquí es donde se desarrollará la mayor parte de la acción.</p><p>La clase <strong><strong>Blockchain</strong></strong> tendrá varios métodos auxiliares para completar varias tareas en la cadena de bloques.</p><p>Permíteme explicar el papel de cada uno de los métodos en la clase.</p><h3 id="a-m-todo-constructor"><strong>a. Método constructor</strong></h3><p>Este método garantiza que se cree una instancia de la cadena de bloques.</p><pre><code class="language-python">class BlockChain:

    def __init__(self):
        self.chain = []
        self.current_data = []
        self.nodes = set()
        self.construct_genesis()
</code></pre><p>Estos son los roles de sus atributos:</p><ul><li><strong><strong>self.chain</strong></strong> —esta variable mantiene todos los bloques;</li><li><strong><strong>self.current_data</strong></strong> —esta variable mantiene todas las transacciones completadas en el bloque;</li><li><strong><strong>self.construct_genesis()</strong></strong> —este método se encargará de construir el bloque inicial.</li></ul><h3 id="b-construyendo-el-bloque-de-g-nesis"><strong>b. Construyendo el bloque de génesis</strong></h3><p>La cadena de bloques requiere un método <em><em><strong><strong>construct_genesis</strong></strong></em></em> para construir el bloque inicial en la cadena. En la convención de la cadena de bloques, este bloque es especial porque simboliza el inicio de la cadena de bloques.</p><p>En este caso, construyámoslo simplemente pasando algunos valores predeterminados al método <em><em><strong><strong>construct_block</strong></strong></em></em>.</p><p>Le di a <em><em><strong><strong>proof_no</strong></strong></em></em> y <em><em><strong><strong>prev_hash</strong></strong></em></em> un valor de cero, aunque puedes proporcionar cualquier valor que desees.</p><pre><code class="language-python">def construct_genesis(self):
    self.construct_block(proof_no=0, prev_hash=0)


def construct_block(self, proof_no, prev_hash):
    block = Block(
        index=len(self.chain),
        proof_no=proof_no,
        prev_hash=prev_hash,
        data=self.current_data)
    self.current_data = []

    self.chain.append(block)
    return block
</code></pre><h3 id="c-construyendo-nuevos-bloques-"><strong>C. Construyendo nuevos bloques.</strong></h3><p>El método <strong><strong><em><em>construct_block</em></em> </strong></strong>se utiliza para crear nuevos bloques en la cadena de bloques.</p><p>Esto es lo que está ocurriendo con los diversos atributos de este método:</p><ul><li><strong>index</strong>—esto representa la longitud de la cadena de bloques;</li><li><strong><strong>proof_nor &amp; prev_hash</strong></strong> —el método que llama los pasa;</li><li><strong><strong>data</strong></strong> — contiene un registro de todas las transacciones que no están incluidas en ningún bloque del nodo;</li><li><strong><strong>self.current_data</strong></strong>: se usa para restablecer la lista de transacciones en el nodo. Si se ha construido un bloque y se le han asignado transacciones, la lista se restablece para garantizar que se agreguen transacciones futuras a esta lista. Y, este proceso se llevará a cabo continuamente;</li><li><strong><strong>self.chain.append()—</strong></strong> este método une bloques recién construidos a la cadena;</li><li><strong><strong>return</strong></strong>: por último, se devuelve un objeto de bloque construido.</li></ul><h3 id="d-comprobaci-n-de-validez"><strong>d. Comprobación de validez</strong></h3><p><br>El método <em><em><strong><strong>check_validity</strong></strong></em></em> es importante para evaluar la integridad de la cadena de bloques y garantizar que no haya anomalías.</p><p>Como se mencionó anteriormente, los hashes son esenciales para la seguridad de la cadena de bloques, ya que incluso el más mínimo cambio en el objeto conducirá a la generación de un hash completamente nuevo.</p><p>Por lo tanto, este método <strong><strong><em><em>check_validity</em></em> </strong></strong>usa declaraciones <em><em><strong><strong>if</strong></strong></em></em> para verificar si el hash de cada bloque es correcto.</p><p>También verifica si cada bloque apunta al bloque anterior correcto, comparando el valor de sus hashes. Si todo es correcto, devuelve verdadero; de lo contrario, devuelve falso.</p><pre><code class="language-python">@staticmethod
def check_validity(block, prev_block):
    if prev_block.index + 1 != block.index:
        return False

    elif prev_block.calculate_hash != block.prev_hash:
        return False

    elif not BlockChain.verifying_proof(block.proof_no, prev_block.proof_no):
        return False

    elif block.timestamp &lt;= prev_block.timestamp:
        return False

    return True
</code></pre><h3 id="e-adici-n-de-datos-de-transacciones"><strong>e. Adición de datos de transacciones</strong></h3><p>El método <em><em><strong><strong>new_data</strong></strong></em></em> se utiliza para agregar los datos de las transacciones a un bloque. Es un método muy simple: acepta tres parámetros (detalles del remitente, detalles del destinatario y cantidad) y agrega los datos de la transacción a la lista <em><em><strong><strong>self.current_data</strong></strong></em></em>.</p><p>Cada vez que se crea un nuevo bloque, esta lista se asigna a ese bloque y se restablece una vez más, como se explica en el método <strong><strong><em><em>construct_block</em></em></strong></strong> .</p><p>Una vez que se han agregado los datos de la transacción a la lista, se devuelve el índice del siguiente bloque que se creará.</p><p>Este índice se calcula sumando 1 al índice del bloque actual (que es el último de la cadena de bloques). Los datos ayudarán al usuario a enviar la transacción en el futuro.</p><pre><code class="language-python">def new_data(self, sender, recipient, quantity):
    self.current_data.append({
        'sender': sender,
        'recipient': recipient,
        'quantity': quantity
    })
    return True

</code></pre><h3 id="f-agregar-prueba-de-trabajo"><strong>f. Agregar prueba de trabajo</strong></h3><p>La prueba de trabajo es un concepto que evita el abuso de la cadena de bloques. Simplemente, su objetivo es identificar un número que resuelva un problema después de realizar una cierta cantidad de trabajo de cómputo.</p><p>Si el nivel de dificultad para identificar el número es alto, se desalienta el spam y la manipulación de la cadena de bloques.</p><p>En este caso, usaremos un algoritmo simple que disuade a las personas de minar bloques o crear bloques fácilmente.</p><pre><code class="language-python">@staticmethod
def proof_of_work(last_proof):
    '''this simple algorithm identifies a number f' such that hash(ff') contain 4 leading zeroes
         f is the previous f'
         f' is the new proof
        '''
    proof_no = 0
    while BlockChain.verifying_proof(proof_no, last_proof) is False:
        proof_no += 1

    return proof_no


@staticmethod
def verifying_proof(last_proof, proof):
    #verifying the proof: does hash(last_proof, proof) contain 4 leading zeroes?

    guess = f'{last_proof}{proof}'.encode()
    guess_hash = hashlib.sha256(guess).hexdigest()
    return guess_hash[:4] == "0000"

</code></pre><h3 id="g-conseguir-el-ltimo-bloque"><strong>g. Conseguir el último bloque</strong></h3><p>Por último, el método <strong><strong><em><em>latest_block</em></em> </strong></strong>es un método auxiliar que ayuda a obtener el último bloque de la cadena de bloques. Recuerde que el último bloque es en realidad el bloque actual de la cadena.</p><pre><code class="language-python">@property
    def latest_block(self):
        return self.chain[-1]
</code></pre><h2 id="sumemos-todo-junto"><strong>Sumemos todo junto</strong></h2><p>Aquí está el código completo para crear la criptomoneda <strong><strong>fccCoin</strong></strong> .</p><p>También puedes obtener el código en <a href="https://github.com/Alfrick/Create-Cryptocurrency-in-Python">este repositorio de GitHub.</a></p><pre><code class="language-python">import hashlib
import time


class Block:

    def __init__(self, index, proof_no, prev_hash, data, timestamp=None):
        self.index = index
        self.proof_no = proof_no
        self.prev_hash = prev_hash
        self.data = data
        self.timestamp = timestamp or time.time()

    @property
    def calculate_hash(self):
        block_of_string = "{}{}{}{}{}".format(self.index, self.proof_no,
                                              self.prev_hash, self.data,
                                              self.timestamp)

        return hashlib.sha256(block_of_string.encode()).hexdigest()

    def __repr__(self):
        return "{} - {} - {} - {} - {}".format(self.index, self.proof_no,
                                               self.prev_hash, self.data,
                                               self.timestamp)


class BlockChain:

    def __init__(self):
        self.chain = []
        self.current_data = []
        self.nodes = set()
        self.construct_genesis()

    def construct_genesis(self):
        self.construct_block(proof_no=0, prev_hash=0)

    def construct_block(self, proof_no, prev_hash):
        block = Block(
            index=len(self.chain),
            proof_no=proof_no,
            prev_hash=prev_hash,
            data=self.current_data)
        self.current_data = []

        self.chain.append(block)
        return block

    @staticmethod
    def check_validity(block, prev_block):
        if prev_block.index + 1 != block.index:
            return False

        elif prev_block.calculate_hash != block.prev_hash:
            return False

        elif not BlockChain.verifying_proof(block.proof_no,
                                            prev_block.proof_no):
            return False

        elif block.timestamp &lt;= prev_block.timestamp:
            return False

        return True

    def new_data(self, sender, recipient, quantity):
        self.current_data.append({
            'sender': sender,
            'recipient': recipient,
            'quantity': quantity
        })
        return True

    @staticmethod
    def proof_of_work(last_proof):
        '''this simple algorithm identifies a number f' such that hash(ff') contain 4 leading zeroes
         f is the previous f'
         f' is the new proof
        '''
        proof_no = 0
        while BlockChain.verifying_proof(proof_no, last_proof) is False:
            proof_no += 1

        return proof_no

    @staticmethod
    def verifying_proof(last_proof, proof):
        #verifying the proof: does hash(last_proof, proof) contain 4 leading zeroes?

        guess = f'{last_proof}{proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4] == "0000"

    @property
    def latest_block(self):
        return self.chain[-1]

    def block_mining(self, details_miner):

        self.new_data(
            sender="0",  #it implies that this node has created a new block
            receiver=details_miner,
            quantity=
            1,  #creating a new block (or identifying the proof number) is awarded with 1
        )

        last_block = self.latest_block

        last_proof_no = last_block.proof_no
        proof_no = self.proof_of_work(last_proof_no)

        last_hash = last_block.calculate_hash
        block = self.construct_block(proof_no, last_hash)

        return vars(block)

    def create_node(self, address):
        self.nodes.add(address)
        return True

    @staticmethod
    def obtain_block_object(block_data):
        #obtains block object from the block data

        return Block(
            block_data['index'],
            block_data['proof_no'],
            block_data['prev_hash'],
            block_data['data'],
            timestamp=block_data['timestamp'])

</code></pre><p><br>Ahora, probemos nuestro código para ver si funciona.</p><pre><code class="language-python">blockchain = BlockChain()

print("***Mining fccCoin about to start***")
print(blockchain.chain)

last_block = blockchain.latest_block
last_proof_no = last_block.proof_no
proof_no = blockchain.proof_of_work(last_proof_no)

blockchain.new_data(
    sender="0",  #it implies that this node has created a new block
    recipient="Quincy Larson",  #let's send Quincy some coins!
    quantity=
    1,  #creating a new block (or identifying the proof number) is awarded with 1
)

last_hash = last_block.calculate_hash
block = blockchain.construct_block(proof_no, last_hash)

print("***Mining fccCoin has been successful***")
print(blockchain.chain)
</code></pre><p>¡Funcionó!</p><p>Aquí está el resultado del proceso de minería:</p><pre><code class="language-python">***Mining fccCoin about to start***
[0 - 0 - 0 - [] - 1566930640.2707076]
***Mining fccCoin has been successful***
[0 - 0 - 0 - [] - 1566930640.2707076, 1 - 88914 - a8d45cb77cddeac750a9439d629f394da442672e56edfe05827b5e41f4ba0138 - [{'sender': '0', 'recipient': 'Quincy Larson', 'quantity': 1}] - 1566930640.5363243]
</code></pre><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>¡Ahí tienes!</p><p>Así es como podrías crear tu propia cadena de bloques usando Python.</p><p>Permíteme decir que este tutorial solo demuestra los conceptos básicos para mojarse los pies en la innovadora tecnología blockchain.</p><p>Si <strong><strong>esta moneda</strong></strong> se implementara tal como está, no podría satisfacer las demandas actuales del mercado de una criptomoneda estable, segura y fácil de usar.</p><p>Por lo tanto, aún se puede mejorar agregando características adicionales para mejorar sus capacidades para extraer y enviar transacciones financieras.</p><p>No obstante, es un buen punto de partida si decides dar a conocer tu nombre en el asombroso mundo de las criptomonedas.</p><p>Si tienes algún comentario o pregunta, por favor publícalo a continuación.</p><p>¡Feliz (cripto) codificación!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Qué es Nmap y cómo usarlo: Un tutorial para la mejor herramienta de escaneo de todos los tiempos ]]>
                </title>
                <description>
                    <![CDATA[ Nmap es la herramienta de escaneo más famosa utilizada por los pentesters. En este artículo, veremos algunas características principales de Nmap junto con algunos comandos útiles. ¿Qué es Nmap? Nmap es la abreviatura de Network Mapper. Es una herramienta de línea de comandos de Linux de código abierto que se ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/que-es-nmap-y-como-usarlo-un-tutorial-para-la-mejor-herramienta-de-escaneo-de-todos-los-tiempos/</link>
                <guid isPermaLink="false">643c2b0610657f0643dec840</guid>
                
                    <category>
                        <![CDATA[ Ciberseguridad ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Sun, 23 Apr 2023 01:42:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/04/wall-6.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/what-is-nmap-and-how-to-use-it-a-tutorial-for-the-greatest-scanning-tool-of-all-time/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">What is Nmap and How to Use it – A Tutorial for the Greatest Scanning Tool of All Time</a>
      </p><p>Nmap es la herramienta de escaneo más famosa utilizada por los pentesters. En este artículo, veremos algunas características principales de Nmap junto con algunos comandos útiles.</p><h1 id="-qu-es-nmap"><strong>¿Qué es Nmap?</strong></h1><p>Nmap es la abreviatura de Network Mapper. Es una herramienta de línea de comandos de Linux de código abierto que se utiliza para escanear direcciones IP y puertos en una red y para detectar aplicaciones instaladas.</p><p>Nmap permite a los administradores de red encontrar qué dispositivos se están ejecutando en su red, descubrir puertos y servicios abiertos y detectar vulnerabilidades.</p><p><a href="https://en.wikipedia.org/wiki/Gordon_Lyon" rel="noopener nofollow">Gordon Lyon (seudónimo Fyodor)</a> escribió Nmap como una herramienta para ayudar a mapear una red completa fácilmente y encontrar sus puertos y servicios abiertos.</p><p>Nmap se ha vuelto muy popular y aparece en películas como The Matrix y la popular serie Mr. Robot.</p><h1 id="-por-qu-usar-nmap"><strong>¿Por qué usar Nmap?</strong></h1><p>Hay una serie de razones por las que los profesionales de la seguridad prefieren Nmap a otras herramientas de análisis.</p><p>Primero, Nmap te ayuda a mapear rápidamente una red sin comandos ni configuraciones sofisticados. También admite comandos simples (por ejemplo, para verificar si un host está activo) y secuencias de comandos complejas a través del motor de secuencias de comandos Nmap.</p><p>Otras características de Nmap incluyen:</p><ul><li>Capacidad para reconocer rápidamente todos los dispositivos, incluidos servidores, enrutadores, conmutadores, dispositivos móviles, etc. en redes únicas o múltiples.</li><li>Ayuda a identificar los servicios que se ejecutan en un sistema, incluidos los servidores web, los servidores DNS y otras aplicaciones comunes. Nmap también puede detectar versiones de aplicaciones con una precisión razonable para ayudar a detectar vulnerabilidades existentes.<br></li><li>Nmap puede encontrar información sobre el sistema operativo que se ejecuta en los dispositivos. Puede proporcionar información detallada, como las versiones del sistema operativo, lo que facilita la planificación de enfoques adicionales durante las pruebas de penetración.<br></li><li>Durante la auditoría de seguridad y el escaneo de vulnerabilidades, puedes usar Nmap para atacar sistemas usando scripts existentes del motor de scripting de Nmap.<br></li><li>Nmap tiene una interfaz gráfica de usuario llamada Zenmap. Te ayuda a desarrollar mapeos visuales de una red para una mejor usabilidad y generación de informes.</li></ul><h1 id="comandos"><strong>Comandos</strong></h1><p>Veamos algunos comandos de Nmap. Si no tienes Nmap instalado, puedes <a href="https://nmap.org/download.html" rel="noopener nofollow">obtenerlo desde aquí</a>.</p><h2 id="escaneos-b-sicos"><strong>Escaneos básicos</strong></h2><p>Escanear la lista de dispositivos activos en una red es el primer paso en el mapeo de la red. Hay dos tipos de escaneos que puedes usar para eso:</p><ul><li><strong><strong><strong><strong>Escaneo de ping:</strong></strong></strong></strong> Escanea la lista de dispositivos en funcionamiento en una subred determinada.</li></ul><pre><code>&gt; nmap -sp 192.168.1.1/24</code></pre><ul><li><strong><strong><strong><strong>Escanear un solo host:</strong></strong></strong></strong> Escanea un solo host en busca de 1000 puertos conocidos. Estos puertos son los que utilizan servicios populares como SQL, SNTP, apache y otros.</li></ul><pre><code>&gt; nmap scanme.nmap.org</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/09/1-3.png" class="kg-image" alt="1-3" width="600" height="400" loading="lazy"></figure><h2 id="escaneo-sigiloso"><strong>Escaneo sigiloso</strong></h2><p>El escaneo sigiloso se realiza enviando un paquete SYN y analizando la respuesta. Si se recibe SYN/ACK, significa que el puerto está abierto y puedes abrir una conexión TCP.</p><p>Sin embargo, un escaneo sigiloso nunca completo el <a href="https://www.geeksforgeeks.org/tcp-3-way-handshake-process/" rel="noopener nofollow">protocolo de enlace de 3 vías</a> , lo que dificulta que el objetivo determine el sistema de escaneo.</p><pre><code>&gt; nmap -sS scanme.nmap.org</code></pre><p>Puedes usar el comando <strong><strong><strong><strong>'-sS'</strong></strong></strong></strong> para realizar un escaneo sigiloso. Recuerda, el escaneo sigiloso es más lento y no tan agresivo como los otros tipos de escaneo, por lo que es posible que debas esperar un tiempo para obtener una respuesta.</p><h2 id="escaneo-de-versiones"><strong>Escaneo de versiones</strong></h2><p>Encontrar versiones de aplicaciones es una parte crucial en las pruebas de penetración.</p><p>Te facilita la vida, ya que puedes encontrar una vulnerabilidad existente en la base de datos <a href="https://cve.mitre.org/" rel="noopener nofollow">de Vulnerabilidades y Exploits Comunes (CVE)</a> para una versión particular del servicio. Luego puedes usarlo para atacar una máquina usando una herramienta de explotación como <a href="https://en.wikipedia.org/wiki/Metasploit_Project" rel="noopener nofollow">Metasploit</a> .</p><pre><code>&gt; nmap -sV scanme.nmap.org</code></pre><p>Para hacer un escaneo de versión, usa el comando '-sV'. Nmap proporcionará una lista de servicios con sus versiones. Ten en cuenta que los escaneos de versiones no siempre son 100% precisos, pero te acercan un paso más para ingresar con éxito a un sistema.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/09/1-5.png" class="kg-image" alt="1-5" width="600" height="400" loading="lazy"></figure><h2 id="escaneo-del-sistema-operativo"><strong>Escaneo del sistema operativo</strong></h2><p>Además de los servicios y sus versiones, Nmap puede proporcionar información sobre el sistema operativo subyacente mediante huellas dactilares de TCP/IP. Nmap también intentará encontrar el tiempo de actividad del sistema durante una exploración del sistema operativo.</p><pre><code>&gt; nmap -sV scanme.nmap.org</code></pre><p>Puedes usar las banderas adicionales como osscan-limit para limitar la búsqueda a algunos objetivos esperados. Nmap mostrará el porcentaje de confianza para cada conjetura del sistema operativo.</p><p>Una vez más, la detección del sistema operativo no siempre es precisa, pero contribuye en gran medida a ayudar a un pen tester a acercarse a su objetivo.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/09/1-6.png" class="kg-image" alt="1-6" width="600" height="400" loading="lazy"></figure><h2 id="escaneo-agresivo"><strong>Escaneo agresivo</strong></h2><p>Nmap tiene un modo agresivo que permite la detección del sistema operativo, la detección de versiones, el escaneo de scripts y el rastreo de rutas. Puedes utilizar el argumento -A para realizar un análisis agresivo.</p><pre><code>&gt; nmap -A scanme.nmap.org</code></pre><p>Los escaneos agresivos brindan mucha mejor información que los escaneos regulares. Sin embargo, un análisis agresivo también envía más sondeos y es más probable que se detecte durante las auditorías de seguridad.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/09/1-7.png" class="kg-image" alt="1-7" width="600" height="400" loading="lazy"></figure><h2 id="escaneo-de-varios-hosts"><strong>Escaneo de varios hosts</strong></h2><p>Nmap tiene la capacidad de escanear múltiples hosts simultáneamente. Esta característica es muy útil cuando administras una gran infraestructura de red.</p><p>Puedes escanear múltiples hosts a través de numerosos enfoques:</p><ul><li>Escribe todas las direcciones IP en una sola fila para escanear todos los hosts al mismo tiempo.</li></ul><pre><code>&gt; nmap 192.164.1.1 192.164.0.2 192.164.0.2</code></pre><ul><li>Utiliza el asterisco (*) para escanear todas las subredes a la vez.</li></ul><pre><code>&gt; nmap 192.164.1.*</code></pre><ul><li>Agrega comas para separar las terminaciones de las direcciones en lugar de escribir los dominios completos.</li></ul><pre><code>&gt; nmap 192.164.0.1,2,3,4</code></pre><ul><li>Usa un guion para especificar un rango de direcciones IP</li></ul><pre><code>&gt; nmap 192.164.0.0–255</code></pre><h2 id="escaneo-de-puertos"><strong>Escaneo de puertos</strong></h2><p>El escaneo de puertos es una de las características más fundamentales de Nmap. Puedes buscar puertos de varias maneras.</p><ul><li>Usando el parámetro -p para buscar un solo puerto</li></ul><pre><code>&gt; nmap -p 973 192.164.0.1</code></pre><ul><li>Si especificas el tipo de puerto, puedes buscar información sobre un tipo particular de conexión, por ejemplo, para una conexión TCP.</li></ul><pre><code>&gt; nmap -p T:7777, 973 192.164.0.1</code></pre><ul><li>Se puede escanear un rango de puertos separándolos con un guion.</li></ul><pre><code>&gt; nmap -p 76–973 192.164.0.1</code></pre><ul><li>También puede usar el indicador <strong><strong><strong><strong>-top-ports</strong></strong></strong></strong> para especificar los n puertos principales para escanear.</li></ul><pre><code>&gt; nmap --top-ports 10 scanme.nmap.org</code></pre><h2 id="escaneo-desde-un-archivo"><strong>Escaneo desde un archivo</strong></h2><p>Si deseas escanear una gran lista de direcciones IP, puedes hacerlo importando un archivo con la lista de direcciones IP.</p><pre><code>&gt; nmap -iL /input_ips.txt</code></pre><p>El comando anterior producirá los resultados del escaneo de todos los dominios dados en el archivo "input_ips.txt". Además de simplemente escanear las direcciones IP, también puedes usar opciones y banderas adicionales.</p><h2 id="verbosidad-y-exportaci-n-de-resultados-de-escaneo"><strong>Verbosidad y exportación de resultados de escaneo</strong></h2><p>Las pruebas de penetración pueden durar días o incluso semanas. Exportar los resultados de Nmap puede ser útil para evitar trabajo redundante y ayudar a crear informes finales. Veamos algunas formas de exportar los resultados del escaneo de Nmap.</p><h3 id="salida-detallada"><strong>Salida detallada</strong></h3><pre><code>&gt; nmap -v scanme.nmap.org</code></pre><p>La salida detallada proporciona información adicional sobre el análisis que se está realizando. Es útil monitorear paso a paso las acciones que Nmap realiza en una red, especialmente si eres un extraño que escanea la red de un cliente.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/09/1-8.png" class="kg-image" alt="1-8" width="600" height="400" loading="lazy"></figure><h3 id="salida-normal"><strong>Salida normal</strong></h3><p>Los escaneos de Nmap también se pueden exportar a un archivo de texto. Será ligeramente diferente de la salida de la línea de comandos original, pero capturará todos los resultados de escaneo esenciales.</p><pre><code>&gt; nmap -oN output.txt scanme.nmap.org</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/09/1-9.png" class="kg-image" alt="1-9" width="600" height="400" loading="lazy"></figure><h3 id="salida-xml"><strong>Salida XML</strong></h3><p>Los escaneos de Nmap también se pueden exportar a XML. También es el formato de archivo preferido de la mayoría de las herramientas de prueba de penetración, lo que lo hace fácilmente analizable al importar resultados de escaneo.</p><pre><code>&gt; nmap -oX output.xml scanme.nmap.org</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/09/1-10.png" class="kg-image" alt="1-10" width="600" height="400" loading="lazy"></figure><h3 id="m-ltiples-formatos"><strong>Múltiples Formatos</strong></h3><p>También puedes exportar los resultados del escaneo en todos los formatos disponibles a la vez usando el comando -oA.</p><pre><code>&gt; nmap -oA output scanme.nmap.org</code></pre><p>El comando anterior exportará el resultado del escaneo en tres archivos: salida.xml, salida. Nmap y salida.gnmap.</p><h2 id="ayuda-nmap"><strong>Ayuda Nmap</strong></h2><p>Nmap tiene un comando de ayuda incorporado que enumera todas las banderas y opciones que puedes usar. A menudo es útil dada la cantidad de argumentos de línea de comandos con los que viene Nmap.</p><pre><code>&gt; nmap -h</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/09/1-12.png" class="kg-image" alt="1-12" width="600" height="400" loading="lazy"></figure><h1 id="motor-de-secuencias-de-comandos-nmap"><strong>Motor de secuencias de comandos Nmap</strong></h1><p>Nmap Scripting Engine (NSE) es una herramienta increíblemente poderosa que puedes usar para escribir scripts y automatizar numerosas funciones de red.</p><p>Puedes encontrar muchos scripts distribuidos en Nmap o escribir tu propio script según tus requisitos. Incluso puedes modificar scripts existentes usando el <a href="https://en.wikipedia.org/wiki/Lua_(programming_language)" rel="noopener nofollow">lenguaje de programación Lua</a> .</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/09/1-13.png" class="kg-image" alt="1-13" width="600" height="400" loading="lazy"></figure><p>NSE también tiene secuencias de comandos de ataque que se utilizan para atacar la red y varios protocolos de red.</p><p>Repasar el motor de secuencias de comandos en profundidad estaría fuera del alcance de este artículo, por lo que <a href="https://nmap.org/book/nse.html" rel="noopener nofollow">aquí hay más información sobre el motor de secuencias de comandos Nmap.</a></p><h2 id="zenmap"><strong>Zenmap</strong></h2><p>Zenmap es una interfaz gráfica de usuario para Nmap. Es un software gratuito y de código abierto que te ayuda a comenzar a utilizar Nmap.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2020/09/1-15.png" class="kg-image" alt="1-15" width="600" height="400" loading="lazy"></figure><p>Además de proporcionar mapeos de red visuales, Zenmap también te permite guardar y buscar tus escaneos para uso futuro.</p><p>Zenmap es excelente para los principiantes que desean probar las capacidades de Nmap sin pasar por una interfaz de línea de comandos.</p><h1 id="conclusi-n"><strong>Conclusión</strong></h1><p>Nmap es claramente la "navaja suiza" de las redes, gracias a su inventario de comandos versátiles.</p><p>Te permite escanear y descubrir rápidamente información esencial sobre tu red, hosts, puertos, firewalls y sistemas operativos.</p><p>Nmap tiene numerosas configuraciones, indicadores y preferencias que ayudan a los administradores de sistemas a analizar una red en detalle.</p><p>Si deseas aprender Nmap en profundidad, <a href="https://github.com/jasonniebauer/Nmap-Cheatsheet" rel="noopener nofollow">este es un gran recurso</a>.</p><p><em><em><em><em>¿Te encantó este artículo? </em></em></em></em><a href="http://tinyletter.com/manishmshiva" rel="noopener nofollow"><strong><strong><strong><strong><em><em><em><em>Únete a mi Newsletter</em></em></em></em></strong></strong></strong></strong></a><em><em><em><em> y recibe un resumen de mis artículos y videos todos los lunes.</em></em></em></em></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ El comando Tar en Linux: Tar CVF y Tar XVF explicados con comandos de ejemplo ]]>
                </title>
                <description>
                    <![CDATA[ El nombre tares la abreviatura de archivo de cinta . Las "cintas" en cuestión serían todas esas unidades de almacenamiento magnético que fueron populares en la década de 1950. Esto sugiere que la herramienta tar podría ser un poco vieja y haber pasado su mejor momento. Pero la verdad es ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/comando-tar-linux-tar-cvf-tar-xvf/</link>
                <guid isPermaLink="false">64345ac710657f0643debe5b</guid>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Sun, 23 Apr 2023 01:02:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/04/5f9c9938740569d1a4ca1e84.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/tar-command-linux-tar-cvf-tar-xvf/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Tar Command in Linux: Tar CVF and Tar XVF Explained with Example Commands</a>
      </p><p>El nombre <code>tar</code>es la abreviatura de <em><em>archivo de cinta</em></em> . Las "cintas" en cuestión serían todas esas unidades de almacenamiento magnético que fueron populares en la década de 1950.</p><p>Esto sugiere que la herramienta <code>tar</code> podría ser un poco vieja y haber pasado su mejor momento. Pero la verdad es que, a lo largo de los años y a través de todos los cambios sísmicos en el mundo de TI, <code>tar</code> no ha perdido nada de su poder y valor.</p><p>En este artículo, basado en el contenido de mi <a href="https://www.amazon.com/gp/product/1617294934/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1617294934&amp;linkCode=as2&amp;tag=projemun-20&amp;linkId=1a460c0cd9a39e01821133b90632cba8">libro Linux en acción (en inglés)</a>, te mostraré los conceptos básicos de la creación, compresión y restauración de archivos tar. Empecemos desde el principio.</p><h1 id="creando-archivos"><strong>Creando archivos</strong></h1><p>Este ejemplo cogerá todos los archivos y directorios dentro y debajo del directorio de trabajo actual y creará un archivo de almacenamiento que he llamado <code>nombredearchivo.tar</code>.</p><p>Aquí uso tres argumentos después del comando tar:</p><ul><li>la <code>c</code>le dice a tar que cree un nuevo archivo,</li><li><code>v</code>establece la salida por pantalla con detalle para recibir actualizaciones, y</li><li><code>f</code>apunta al nombre de archivo que me gustaría darle al archivo.</li></ul><p>El <code>*</code>es lo que le indica a <code>tar</code> que incluya todos los archivos y directorios locales de forma recursiva.</p><pre><code>$ tar cvf nombredearchivo.tar *
archivo1
archivo2
archivo3
directorio1
directorio1/mascosas
directorio1/mascosas/archivo100
directorio1/mascosas/archivo101
</code></pre><p>El comando tar nunca moverá ni eliminará ninguno de los directorios y archivos originales que le proporciones, solo hace copias archivadas.</p><p>También debes tener en cuenta que el uso de un punto (.) en lugar de un asterisco (*) en el comando anterior incluiría incluso archivos ocultos (cuyos nombres de archivo comienzan con un punto) en el archivo.</p><p>Si lo estás haciendo en tu propio ordenador (como deberías), verás un nuevo archivo llamado nombredearchivo.tar. La extensión de nombre de archivo .tar no es necesaria, pero siempre es una buena idea comunicar claramente el propósito de un archivo de tantas formas como sea posible.</p><p>Extraer tu archivo para restaurar los archivos es fácil: simplemente usa <code>xvf</code>en lugar de <code>cvf</code>. Eso, en el ejemplo, guardará nuevas copias de los archivos y directorios originales en la ubicación actual.</p><pre><code>$ tar xvf nombredearchivo.tar
archivo1
archivo2
archivo3
directorio1
directorio1/mascosas
directorio1/mascosas/archivo100
directorio1/mascosas/archivo101</code></pre><p>Por supuesto, también puedes hacer que tar envíe sus archivos extraídos a algún otro lugar usando el argumento <code>-C</code>, seguido de la ubicación de destino:</p><pre><code>$ tar xvf nombredearchivo.tar -C /home/misdatos/archivosantiguos/</code></pre><p>No siempre querrás incluir todos los archivos dentro de un árbol de directorios en tu archivo.</p><p>Supongamos que has producido algunos videos, pero actualmente están guardados en directorios junto con todo tipo de archivos gráficos, de audio y de texto (que contienen tus notas). Los únicos archivos que necesitas respaldar son los clips de video finales con la extensión de nombre de archivo .mp4.</p><p>Así es como se hace:</p><pre><code>$ tar cvf nombredearchivo.tar *.mp4</code></pre><p>Genial. Pero esos archivos de video son enormes. ¿No sería bueno hacer ese archivo un poco más pequeño usando compresión?</p><p>¡No digas más! Simplemente, ejecuta el comando anterior con el argumento <code>z</code> (zip). Eso le dirá al programa gzip que comprima el archivo.</p><p>Si deseas seguir la convención, también puedes agregar una extensión <code>.gz</code> además de la <code>.tar</code>que ya existe. Recuerda: claridad.</p><p>Así es como se haría:</p><pre><code>$ tar czvf nombredearchivo.tar.gz *.mp4</code></pre><p>Si pruebas esto en tus propios archivos .mp4 y luego ejecutas ls -l en el directorio que contiene los nuevos archivos, puedes notar que el archivo <code>.tar.gz</code> no es mucho más pequeño que el archivo <code>.tar</code>, quizás un 10% más o menos. ¿Por qué?</p><p>Bueno, el formato <code>.mp4</code> del archivo está comprimido, por lo que hay mucho menos margen para que gzip haga su trabajo.</p><p>Como tar es plenamente consciente de tu entorno Linux, puedes usarlo para seleccionar archivos y directorios que están fuera de tu directorio de trabajo actual. Este ejemplo agrega todos los archivos <code>.mp4</code> en el directorio <code>/home/miusuario/Videos/</code>:</p><pre><code>$ tar czvf archivename.tar.gz /home/myuser/Videos/*.mp4
</code></pre><p>Debido a que los archivos de almacenamiento pueden aumentar de tamaño, a veces puede tener sentido dividirlos en varios archivos más pequeños, transferirlos a su nuevo destino y luego volver a crear el archivo original en el otro extremo. La herramienta de división está hecha para este propósito.</p><p>En este ejemplo, <code>-b</code> le dice a Linux que divida el archivo nombredearchivo.tar.gz en partes de 1 GB. Luego, la operación nombra cada una de las partes: nombredearchivo.tar.gz.partaa, nombredearchivo.tar.gz.partab, nombredearchivo.tar.gz.partac, etc.:</p><pre><code>$ split -b 1G nombredearchivo.tar.gz "nombredearchivo.tar.gz.part"</code></pre><p>Por otro lado, vuelve a crear el archivo leyendo cada una de las partes en secuencia (cat nombredearchivo.tar.gz.part*), luego redirige la salida a un nuevo archivo llamado nombredearchivo.tar.gz:</p><pre><code>$ cat nombredearchivo.tar.gz.part* &gt; nombredearchivo.tar.gz</code></pre><h1 id="transmisi-n-de-archivos-del-sistema-de-archivos"><strong>Transmisión de archivos del sistema de archivos</strong></h1><p>Aquí es donde empieza lo bueno. Te mostraré cómo crear una imagen de archivo de una instalación de Linux en funcionamiento y transmitirla a una ubicación de almacenamiento remota, todo con un solo comando. Aquí está el comando:</p><pre><code># tar czvf - --one-file-system / /usr /var \
  --exclude=/home/andy/ | ssh username@10.0.3.141 \
  "cat &gt; /home/username/workstation-backup-Apr-10.tar.gz"
</code></pre><p>En lugar de tratar de explicar todo eso de inmediato, usaré ejemplos más pequeños para explorarlo pieza por pieza.</p><p>Vamos a crear un archivo de los contenidos de un directorio llamado cosasimportantes que está lleno de, bueno, cosas realmente importantes:</p><pre><code>$ tar czvf - cosasimportantes/ | ssh usuario@10.0.3.141 "cat &gt; /home/usuario/misarchivos.tar.gz"
cosasimportantes/nombredearchivo1
cosasimportantes/nombredearchivo2
[...]
usuario@10.0.3.141's password:
</code></pre><p>Déjame explicarte este ejemplo. En lugar de ingresar el nombre del archivo justo después de los argumentos del comando (como lo has hecho hasta ahora), usé un guion (czvf -).</p><p>El guion envía datos a la salida estándar. Te permite enviar los detalles del nombre del archivo al final del comando y le dice a tar que espere el contenido de origen del archivo en su lugar.</p><p>Luego canaliza (|) el archivo comprimido sin nombre a un inicio de sesión ssh en un servidor remoto donde me pidieron mi contraseña.</p><p>El comando que va entre comillas ejecuta cat contra el flujo de datos de archivo, el cual escribió el contenido del flujo en un archivo llamado myfiles.tar.gz en mi directorio de inicio del host remoto.</p><p>Una ventaja de generar archivos de esta manera es que evita la sobrecarga de un paso intermedio. No hay necesidad de guardar temporalmente una copia del archivo en la máquina local. Imagina hacer una copia de seguridad de una instalación que ocupa 110 GB de sus 128 GB de espacio disponible. ¿Dónde iría el archivo?</p><p>Esto era solo un directorio de archivos. Supongamos que necesitas hacer una copia de seguridad de un sistema operativo Linux activo en una unidad USB para poder moverlo a una máquina separada y colocarlo en la unidad principal de esa máquina.</p><p>Partiendo de la base de que ya existe una instalación nueva de la misma versión de Linux en la segunda máquina, la próxima operación de copiar/pegar generará una réplica exacta de la primera.</p><blockquote>NOTA: Esto no funcionará en una unidad de destino que aún no tenga instalado un sistema de archivos Linux. Para manejar esa situación, deberá usar <code>dd</code>.</blockquote><p>El siguiente ejemplo crea un archivo comprimido en la unidad USB conocido como <code>/dev/sdc1</code>.</p><p>El argumento <code>--one-file-system</code> excluye todos los datos de cualquier sistema de archivos, además del actual. Esto significa que las pseudoparticiones como <code>/sys/</code>y <code>/dev/</code>no se agregarán al archivo. Si hay otras particiones que deseas incluir (como lo harás para <code>/usr/</code>y <code>/var/</code>en este ejemplo), deben agregarse explícitamente.</p><p>Finalmente, puedes excluir datos del sistema de archivos actual usando el argumento <code>--exclude</code>:</p><pre><code># tar czvf /dev/sdc1/workstation-backup-Apr-10.tar.gz \
  --one-file-system \
  / /usr /var \
  --exclude=/home/usuario/</code></pre><p>Ahora volvamos a ese ejemplo de comando de servicio completo. Usando lo que ya aprendiste, archiva todos los directorios importantes de un sistema de archivos y copia el archivo en una unidad USB. Debería tener sentido para ti ahora:</p><pre><code># tar czvf - --one-file-system / /usr /var \
  --exclude=/home/usuario/ | ssh usuario@10.0.3.141 \
  "cat &gt; /home/usuario/workstation-backup-Apr-10.tar.gz"
</code></pre><p><em><em><em><em><em><em><em><em><em><em><em><em><em><em><em><em>Hay muchas más bondades de administración en forma de libros, cursos y artículos disponibles en mi <a href="https://bootstrap-it.com/">bootstrap-it.com</a>.</em></em></em></em></em></em></em></em></em></em></em></em></em></em></em></em></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ ¿Qué es msmpeng.exe? ¿Por qué consume tanta CPU? ]]>
                </title>
                <description>
                    <![CDATA[ Msmpeng.exe es una parte importante de la seguridad de Windows, anteriormente conocida como Windows Defender. Escanea tu computadora en busca de varias amenazas, desde malware hasta spyware, y luego ofrece la(s) solución(es) adecuada(s). En este artículo, te mostraré qué es mempeng.exe, la razón por la que consume demasiada CPU y ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/que-es-msmpeng-exe-porque-consume-tanta-cpu/</link>
                <guid isPermaLink="false">6429e979cbd6cf076f06ad46</guid>
                
                    <category>
                        <![CDATA[ Seguridad ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Thu, 20 Apr 2023 18:47:32 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/04/joseph-greve-BPJKc4r7_eo-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/what-is-msmpeng-exe-why-is-it-of-high-cpu-disk-usage/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">What is msmpeng.exe? Why is it High CPU Disk Usage?</a>
      </p><p>Msmpeng.exe es una parte importante de la seguridad de Windows, anteriormente conocida como Windows Defender. Escanea tu computadora en busca de varias amenazas, desde malware hasta spyware, y luego ofrece la(s) solución(es) adecuada(s).</p><p>En este artículo, te mostraré qué es mempeng.exe, la razón por la que consume demasiada CPU y 2 formas diferentes de evitar que use tanta CPU.</p><h2 id="-qu-es-msmpeng-exe"><strong>¿Qué es msmpeng.exe?</strong></h2><p>Msmpeng.exe significa motor de protección contra malware de Microsoft. También conocido como ejecutable del servicio Antimalware, es el programa antivirus incorporado para ordenadores con Windows 10.</p><p>Este programa se ejecuta en segundo plano y escanea tu ordenador en busca de amenazas como software dañino, virus, gusanos, etc., luego los pone en cuarentena o los elimina.</p><h2 id="-por-qu-msmpeng-exe-consume-tanta-cpu"><strong>¿Por qué msmpeng.exe consume tanta CPU?</strong></h2><p>Msmpeng.exe consume demasiados recursos de la CPU porque se ejecuta activamente en segundo plano y mientras tanto escanea cada parte de tu &nbsp;ordenador. Por supuesto, esto hace que msmpeng.exe sea un programa que consume muchos recursos.</p><p>Aparte de eso, otra razón por la que msmpeng.exe usa una gran cantidad de CPU es que el programa escanea su propia carpeta (<code>C:\Program Files\Windows Defender</code>). Los bajos recursos de hardware también se han relacionado con msmpeng.exe que consume demasiados recursos de la CPU.</p><h2 id="c-mo-evitar-que-msmpeng-exe-use-demasiados-recursos-de-la-cpu"><strong>Cómo evitar que msmpeng.exe use demasiados recursos de la CPU</strong></h2><p>Hay 2 formas principales de evitar que el ejecutable del servicio Antimalware de Windows 10 use demasiada CPU. En primer lugar, puedes evitar que Windows Defender escanee su propia carpeta y deshabilite la protección en tiempo real y, en segundo lugar, puedes reprogramar los análisis de Windows Defender.</p><h3 id="soluci-n-1-evita-que-windows-defender-escanee-su-propia-carpeta"><strong>Solución 1: Evita que Windows Defender escanee su propia carpeta</strong></h3><p><strong><strong>Paso 1</strong></strong>: Haz clic en Inicio o presiona la tecla WIN en tu teclado, luego haz clic en el icono de ajustes para abrir la aplicación Configuración.<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen1.png" class="kg-image" alt="ss-1-7" width="504" height="584" loading="lazy"></figure><p><br><strong><strong>Paso 2</strong></strong> : Haz clic en "Actualización y seguridad" de la lista.<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen2.png" class="kg-image" alt="ss-2-8" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen2.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2023/04/imagen2.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen2.png 1111w" sizes="(min-width: 720px) 720px" width="1111" height="628" loading="lazy"></figure><p><strong><strong>Paso 3</strong></strong> : Selecciona "Seguridad de Windows" y haz clic en "Protección contra virus y amenazas".<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen3.png" class="kg-image" alt="ss-3-6" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen3.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen3.png 801w" sizes="(min-width: 720px) 720px" width="801" height="628" loading="lazy"></figure><p><strong><strong>Paso 4</strong></strong> : Se abrirá la aplicación de seguridad de Windows. En "Configuración de antivirus y protección contra amenazas", haz clic en el enlace "Administrar la configuración".<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen4.png" class="kg-image" alt="ss-4-7" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen4.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen4.png 654w" width="654" height="621" loading="lazy"></figure><p><strong><strong>Paso 5</strong></strong> : Desplázate hacia abajo hasta "Exclusiones" y haz clic en el enlace "Agregar o quitar exclusiones".<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen5.png" class="kg-image" alt="ss-5-3" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen5.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen5.png 632w" width="632" height="632" loading="lazy"></figure><p><strong><strong>Paso 6</strong></strong> : En la página siguiente, haz clic en "Agregar exclusión", luego selecciona "Carpeta".<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen6.png" class="kg-image" alt="ss-6-5" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen6.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen6.png 618w" width="618" height="629" loading="lazy"></figure><p><strong><strong>Paso 7</strong></strong> : Para evitar múltiples clics, pega “ <code>C:\Program Files\Windows Defender</code>” en el editor y haz clic en “Seleccionar carpeta”.<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen7.png" class="kg-image" alt="ss-7-3" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen7.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen7.png 670w" width="670" height="468" loading="lazy"></figure><p><strong><strong>Paso 8</strong></strong>: Inmediatamente después de hacer clic en "Seleccionar carpeta", aparecerá una ventana de confirmación; asegúrate de hacer clic en Sí.</p><p>Ahora puedes ver que la carpeta se ha agregado como una exclusión:<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen8.png" class="kg-image" alt="ss-8-1" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen8.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen8.png 655w" width="655" height="634" loading="lazy"></figure><p>Windows Defender ya no escaneará esta carpeta, por lo que la tasa de uso de la CPU debería disminuir en tu ordenador.</p><h3 id="soluci-n-2-deshabilita-la-protecci-n-en-tiempo-real-y-reprograma-los-an-lisis-de-windows-defender"><strong>Solución 2: Deshabilita la protección en tiempo real y reprograma los análisis de Windows Defender</strong></h3><p><strong><strong>Paso 1</strong></strong>: Para desactivar la protección en tiempo real y reprogramar los análisis realizados por Windows Defender, presiona <code>WIN</code>(tecla de Windows) para abrir el cuadro de diálogo Ejecutar.</p><p><strong><strong>Paso 2</strong></strong>: Escribe "taskschd.msc" y haz clic en "Aceptar". Esto abrirá la aplicación Programador de tareas.<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen9.png" class="kg-image" alt="ss-9" width="397" height="202" loading="lazy"></figure><p><strong><strong>Paso 3</strong></strong> : Expande la pestaña "Programador de tareas", luego selecciona "Microsoft" y luego "Windows".<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen10.png" class="kg-image" alt="ss-10" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen10.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen10.png 938w" sizes="(min-width: 720px) 720px" width="938" height="562" loading="lazy"></figure><p><strong><strong>Paso 4</strong></strong> : Desplázate hacia abajo y selecciona "Windows Defender".<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen11.png" class="kg-image" alt="ss-11" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen11.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen11.png 936w" sizes="(min-width: 720px) 720px" width="936" height="563" loading="lazy"></figure><p><strong><strong>Paso 5</strong></strong> : Haz clic derecho en "Windows Defender Scheduled Scan" y selecciona "Propiedades".</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen12.png" class="kg-image" alt="ss-12" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen12.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen12.png 933w" sizes="(min-width: 720px) 720px" width="933" height="560" loading="lazy"></figure><p><strong><strong>Paso 6</strong></strong> : En la pestaña General, desmarca "Ejecutar con los privilegios más altos".<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen13-1.png" class="kg-image" alt="ss-13" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen13-1.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen13-1.png 935w" sizes="(min-width: 720px) 720px" width="935" height="561" loading="lazy"></figure><p><strong><strong>Paso 7</strong></strong> : Ves a la pestaña Condiciones y asegúrate de que todas las casillas estén desmarcadas.<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen14.png" class="kg-image" alt="ss-14" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen14.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen14.png 936w" sizes="(min-width: 720px) 720px" width="936" height="561" loading="lazy"></figure><p><strong><strong>Paso 7</strong></strong> : Por último, ves a la pestaña Desencadenadores y haz clic en "Nuevo".<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen15.png" class="kg-image" alt="ss-15" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen15.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen15.png 931w" sizes="(min-width: 720px) 720px" width="931" height="561" loading="lazy"></figure><p><strong><strong>Paso 8</strong></strong>: Finalmente, programa la hora a la que deseas que Windows Defender ejecute los análisis, elige la frecuencia, la fecha y la hora, luego haz clic en "Aceptar". Haz clic en "Aceptar" de nuevo.<br></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen16.png" class="kg-image" alt="ss-16" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/04/imagen16.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/04/imagen16.png 936w" sizes="(min-width: 720px) 720px" width="936" height="563" loading="lazy"></figure><p><strong><strong>Paso 8</strong></strong> : Reinicia tu ordenador. Con esto, msmpeng.exe ya no debería consumir tantos recursos de la CPU.</p><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>Msmpeng.exe, también conocido como ejecutable del servicio Antimalware, es un programa relevante y efectivo que protege tu ordenador de amenazas.</p><p>Al mismo tiempo, consume demasiados recursos de la CPU, lo que podría ralentizar tu ordenador y reducir la duración de la batería, por lo que podrías tener la tentación de desactivarlo.</p><p>Dado que las protecciones que ofrece msmpeng.exe son útiles, debes buscar formas de minimizar sus acciones en lugar de deshabilitarlas permanentemente, así cómo este artículo te mostró cómo de hacerlo.</p><p>Si el uso de la CPU no se reduce, puedes intentar deshabilitar Windows Defender de forma permanente, pero asegúrate de obtener otro programa antivirus para tu ordenador si lo haces.</p><p>Gracias por leer este artículo. Considera compartirlo con tus amigos y familiares si lo encuentras útil.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Arreglo Bash: Cómo declarar un arreglo de cadenas en un script Bash ]]>
                </title>
                <description>
                    <![CDATA[ Los scripts de Bash te otorgan una forma conveniente de automatizar las tareas de la línea de comandos. Con Bash, puedes hacer muchas de las cosas que harías en otros lenguajes de secuencias de comandos o programación. Puedes crear y usar variables, ejecutar bucles, usar lógica condicional y almacenar datos ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/arreglo-bash-como-declarar-un-arreglo-de-cadenas-en-un-script-bash/</link>
                <guid isPermaLink="false">6429b31fcbd6cf076f06abe0</guid>
                
                    <category>
                        <![CDATA[ bash ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Mon, 10 Apr 2023 19:21:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/04/pexels-belle-co-1000445.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/bash-array-how-to-declare-an-array-of-strings-in-a-bash-script/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Bash Array – How to Declare an Array of Strings in a Bash Script</a>
      </p><p>Los scripts de Bash te otorgan una forma conveniente de automatizar las tareas de la línea de comandos.</p><p>Con Bash, puedes hacer muchas de las cosas que harías en otros lenguajes de secuencias de comandos o programación. Puedes crear y usar variables, ejecutar bucles, usar lógica condicional y almacenar datos en arreglos.</p><p>Si bien la funcionalidad puede ser muy familiar, la sintaxis de Bash puede ser complicada. En este artículo, aprenderás cómo declarar arreglos y luego cómo usarlos en tu código.</p><h2 id="c-mo-declarar-un-arreglo-en-bash"><strong>Cómo declarar un </strong>arreglo<strong> en Bash</strong></h2><p>Declarar un arreglo en Bash es fácil, pero presta atención a la sintaxis. Si estás acostumbrado a programar en otros lenguajes, el código puede parecerle familiar, pero hay diferencias sutiles que es fácil que te pasen por alto.</p><p>Para declarar tu arreglo, sigue estos pasos:</p><ol><li>Dale un nombre a tu arreglo</li><li>Seguido a ese nombre de variable pon un signo igual. El signo igual <em><em>no debe</em></em> tener espacios a su alrededor.</li><li>Encierra el arreglo entre <em><em>paréntesis</em></em> (no corchetes como en JavaScript)</li><li>Escribe tus cadenas usando comillas, pero sin <em><em>comas</em></em> entre ellas</li></ol><p>Tu declaración de arreglo se verá así:</p><pre><code class="language-sh">miArreglo=("gato" "perro" "ratón" "rana")</code></pre><p>¡Eso es todo! Así de simple.</p><h2 id="c-mo-acceder-a-un-arreglo-en-bash"><strong>Cómo acceder a un </strong>arreglo<strong> en Bash</strong></h2><p>Hay un par de formas diferentes de recorrer tu arreglo. Puedes recorrer los elementos mismos o recorrer los índices.</p><h3 id="c-mo-hacer-un-bucle-a-trav-s-de-los-elementos-de-un-arreglo"><strong>Cómo hacer un bucle a través de los elementos de un </strong>arreglo</h3><p>Para recorrer los elementos del arreglo, tu código debe verse así:</p><pre><code class="language-sh">for str in ${miArreglo[@]}; do
  echo $str
done</code></pre><p>Para desglosarlo: Es algo así como usar <code>forEach</code> en JavaScript. Para cada cadena (str) en el arreglo (miArreglo), imprime esa cadena.</p><p>La salida de este bucle se ve así:</p><pre><code>gato
perro
ratón
rana</code></pre><p><strong><strong>Nota</strong></strong>: El símbolo <code>@</code> entre corchetes indica que está recorriendo <em><em>todos</em></em> los elementos del arreglo. Si tuvieras que omitir eso y simplemente escribir <code>for str in ${miArray}</code>, solo se imprimiría la primera cadena de caracteres del arreglo.</p><h3 id="c-mo-hacer-un-bucle-a-trav-s-de-ndices-del-arreglo"><strong>Cómo hacer un bucle a través de índices del </strong>arreglo</h3><p>Alternativamente, puedes recorrer los índices del arreglo. Esto es como un bucle <code>for</code> &nbsp;en JavaScript, y es útil cuando deseas poder acceder al índice de cada elemento.</p><p>Para usar este método, tu código deberá tener un aspecto similar al siguiente:</p><pre><code class="language-sh">for i in ${!miArreglo[@]}; do
  echo "El elemento $i es ${miArreglo[$i]}"
done</code></pre><p>La salida se verá así:</p><pre><code>El elemento 0 es gato
El elemento 1 es perro
El elemento 2 es ratón
El elemento 3 es rana</code></pre><p><strong><strong>Nota</strong></strong>: El signo de exclamación al comienzo de la variable <code>miArreglo</code> indica que está accediendo a los <em><em>índices</em></em> del arreglo y no a los elementos en sí. Esto puede ser confuso si estás acostumbrado al signo de exclamación que indica negación, así que presta mucha atención a eso.</p><p><strong><strong>Otra nota</strong></strong>: Bash normalmente no requiere llaves para las variables, pero sí para los arreglos. Entonces verás que cuando hace referencia a un arreglo, lo hace con la sintaxis <code>${miArreglo}</code>, pero cuando hace referencia a una cadena o número, simplemente usa un signo de dólar: <code>$i</code>.</p><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>Los scripts de Bash son útiles para crear un comportamiento de línea de comandos automatizado, y los arreglos son una gran herramienta que puedes usar para almacenar múltiples datos.</p><p>Declararlos y usarlos no es difícil, pero es diferente a otros lenguajes, así que presta mucha atención para no cometer errores.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Diseño web adaptativo: cómo hacer que un sitio web se vea bien en teléfonos y tabletas ]]>
                </title>
                <description>
                    <![CDATA[ En el panorama de los dispositivos conectados evolucionando rápidamente, el diseño web adaptativo (adaptable a cualquier dispositivo) sigue siendo crucial en el desarrollo web. No hace mucho tiempo, el término "diseño web adaptativo" no existía. Pero hoy, la mayoría de nosotros hemos tenido que adoptarlo hasta cierto punto.  Según ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/diseno-web-adaptable-como-hacer-que-un-sitio-web-se-vea-bien-en-telefonos-y-tabletas/</link>
                <guid isPermaLink="false">641e3d3f083d0a0781fde500</guid>
                
                    <category>
                        <![CDATA[ Diseño Web Responsive ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Tue, 04 Apr 2023 01:58:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/03/curve-design-futuristic-lines-911738.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/responsive-web-design-how-to-make-a-website-look-good-on-phones-and-tablets/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Responsive Web Design – How to Make a Website Look Good on Phones and Tablets</a>
      </p><p>En el panorama de los dispositivos conectados evolucionando rápidamente, el diseño web adaptativo (adaptable a cualquier dispositivo) sigue siendo crucial en el desarrollo web.</p><p>No hace mucho tiempo, el término "diseño web adaptativo" no existía. Pero hoy, la mayoría de nosotros hemos tenido que adoptarlo hasta cierto punto.</p><p> <a href="https://www.statista.com/statistics/275814/mobile-share-of-organic-search-engine-visits/">Según (las estadísticas) Statistica</a>, a partir de 2019, el 61% de todas las visitas de búsqueda de Google se realizan en un dispositivo móvil. En septiembre de 2020, <a href="https://webmasters.googleblog.com/2020/03/announcing-mobile-first-indexing-for.html">Google cambiará su algoritmo de búsqueda</a> para priorizar los sitios web compatibles con dispositivos móviles.</p><p><strong>En esta publicación cubriré lo siguiente:</strong></p><ul><li>¿Qué es el diseño web adaptativo? </li><li>La metaetiqueta viewport y lo que hace </li><li>Técnicas efectivas utilizadas en el diseño web responsive para adaptarse a dispositivos móviles y tabletas </li><li>Herramientas para ayudar a simular y monitorizar la experiencia del usuario de dispositivos móviles y tabletas</li></ul><h2 id="-qu-es-el-dise-o-web-adaptativo-rwd-">¿Qué es el diseño web adaptativo? (RWD)</h2><p>El diseño web adaptativo se enfoca en el entorno del usuario de un sitio web. El entorno del usuario dependerá de qué dispositivo tenga conectado a Internet.</p><p>Hay muchas características de los dispositivos que proporcionan oportunidades para un enfoque centrado en el usuario. Algunas de estas incluyen:</p><ul><li>conexión de red </li><li>tamaño de pantalla </li><li>tipo de interacción (pantallas táctiles, almohadillas táctiles) </li><li>resolución de pantalla.</li></ul><p>Antes de que el diseño web adaptativo fuera popular, muchas empresas administraban un sitio web completamente separado que recibía el tráfico reenviado en función del agente de usuario.</p><p>Pero en el diseño web adaptativo, el servidor siempre envía el mismo código HTML a todos los dispositivos, y se usa CSS para alterar la representación de la página en el dispositivo.</p><p>Independientemente de las dos estrategias anteriores, el primer paso para crear un sitio web para teléfono o tableta es asegurarse de que el navegador conozca la intención. Aquí es donde entra en juego la metaetiqueta viewport.</p><h2 id="la-metaetiqueta-viewport-para-identificar-un-sitio-web-m-vil">La metaetiqueta Viewport para identificar un sitio web móvil</h2><p>La metaetiqueta viewport le indica al navegador cómo ajustar la página al ancho de cada dispositivo.</p><p>Cuando el elemento meta viewport está ausente, los navegadores móviles mostrarán páginas web con la configuración de escritorio predeterminada. Esto da como resultado una experiencia aparentemente alejada y no adaptativo.</p><p>A continuación se muestra una implementación estándar:</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;meta name="viewport" content="width=device-width,initial-scale=1"/&gt;</code></pre><figcaption>Ejemplo de metaetiqueta de viewport</figcaption></figure><p>Ahora que el navegador sabe lo que sucede, ¿Podemos utilizar técnicas populares para hacer nuestro sitio web adaptativo?</p><h2 id="consultas-media-css-para-diferentes-tama-os-y-orientaciones-de-pantalla">Consultas @media CSS para diferentes tamaños y orientaciones de pantalla</h2><p>Si eres nuevo en el diseño web adaptativo, las consultas @media son la primera y más importante característica de CSS que debes aprender. Las consultas @media te permiten diseñar elementos según el ancho de la ventana gráfica. Una estrategia popular de CSS es escribir estilos móviles primero y construir sobre ellos con estilos más complejos y específicos de escritorio.</p><p>Las consultas @media son una parte importante del diseño web adaptativo que se usa comúnmente para diseños de cuadrícula, tamaños de fuente, márgenes y relleno que difieren entre el tamaño y la orientación de la pantalla.</p><p>A continuación, se muestra un ejemplo de un caso de uso común de estilo móvil primero en el que una columna tiene un ancho del 100 % para dispositivos más pequeños, pero en viewports más grandes es del 50 %.<br></p><figure class="kg-card kg-code-card"><pre><code class="language-css">.column {
  width: 100%;
}

@media (min-width: 600px) {
  .column {
    width: 50%;
  }
}</code></pre><figcaption>Primer ejemplo de CSS móvil</figcaption></figure><p>El código anterior es un ejemplo simple, pero lo que realmente está haciendo es bastante interesante.</p><ol><li>Al considerar el móvil primero, el elemento "columna" se configura para tener un ancho del 100%; </li><li>Al usar una consulta @media de <code>min-width</code>, definimos reglas específicamente para viewports con un ancho mínimo de <code>600px</code> (ventanas de visualización más anchas que <code>600px</code>). Por lo tanto, para viewports de más de <code>600px</code>, nuestro elemento de columna tendrá un ancho del 50 % de su elemento principal.</li></ol><p>Si bien las consultas @media son esenciales para el diseño web adaptativo, muchas otras características nuevas de CSS también se están adoptando ampliamente y son compatibles con los navegadores. Flexbox es una de estas nuevas e importantes características de CSS en términos de diseño web responsive.</p><h2 id="-qu-es-flexbox">¿Qué es FlexBox?</h2><p>Quizás te estés preguntando: "¿Qué hace Flexbox?" La mejor pregunta es: "¿Qué no puede hacer Flexbox?" ¿Cuál es la forma más fácil de centrar verticalmente con CSS? FlexBox. ¿Cómo se crea una grid layout adaptativo? Flexbox. ¿Cómo podemos lograr la paz mundial? Flexbox.</p><p>El módulo Flexbox Layout (Flexible Box) proporciona una forma más eficiente de diseñar, alinear y distribuir el espacio entre los elementos de un contenedor, incluso cuando su tamaño es dinámico (de ahí la palabra "flex").</p><p>En el siguiente ejemplo, combinamos consultas @media como se explicó anteriormente para crear una cuadrícula adaptativo.</p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;style&gt;
  main {
    background: #d9d7d5;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
  }

  div {
    background: #767775;
    flex-basis: 100%;
    height: 100px;
    margin-bottom: 0.5rem;
  }

  @media (min-width: 600px) {
    main {
      flex-wrap: nowrap;
    }

    div {
      flex-basis: 33%;
    }
  }
&lt;/style&gt;
&lt;main&gt;
  &lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;
&lt;/main&gt;</code></pre><figcaption>Ejemplo de CSS flexbox</figcaption></figure><p>Logramos lo siguiente con este código:</p><ol><li>Establecer un diseño de flexbox con <code>display: flex</code> en nuestro elemento contenedor <code>main</code>.</li><li>Estilo para móvil primero. Configuramos el elemento <code>main</code> a <code>flex-wrap: wrap</code> lo que permite que los elementos secundarios se envuelvan dentro de nuestro diseño de caja flexible (flexbox layout) como se ilustra a continuación en la figura 1. Establecemos &nbsp;<code>flex-basis: 100%</code> en nuestros elementos <code>div</code> para garantizar que abarquen el 100% del ancho principal en el diseño de flexbox (figura 1).</li><li>Estilo para dispositivos más grandes como tabletas y ordenadores de escritorio. Utilizamos una consulta @media similar a nuestro ejemplo de la sección anterior para configurar nuestro elemento <code>main</code> del contenedor a <code>flex-wrap: nowrap</code>. Esto asegura que los elementos secundarios no se ajusten y que mantengan una columna dentro de un tipo de diseño de fila. <br>Al establecer <code>div</code> en &nbsp;<code>flex-basis: 33%</code> dentro de la consulta @media, establecemos columnas que tienen un 33% del ancho del padre (parent).</li><li>En este ejemplo, la magia aparecería en dispositivos más grandes con nuestras reglas combinadas de consultas @media y flexbox. porque definimos <code>display: flex</code> , y debido a que no anulamos la regla dentro de la consulta @media, tenemos un diseño flexible para dispositivos móviles, tabletas y computadoras de escritorio. La consulta @media <code>flex-basis: 33%</code> y las reglas heredadas de <code>display: flex</code> nos darán un diseño de caja flexible reconocible como se ve en la figura 2. En el pasado, para lograr este tipo de diseño de columna, tendríamos que hacer un trabajo arduo y escribir enredos de CSS.</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/07/grid-mobile-1.png" class="kg-image" alt="grid-mobile-1" width="600" height="400" loading="lazy"><figcaption>Figura 1: Ejemplo de cuadrícula de flexbox móvil</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/07/grid-desktop.png" class="kg-image" alt="grid-desktop" width="600" height="400" loading="lazy"><figcaption>Figura 2: Ejemplo de cuadrícula Flexbox de escritorio</figcaption></figure><p>Flexbox proporciona una excelente manera de lograr diseños variados y fluidos. En algunos casos, es posible que no tengamos esa libertad en el espacio vertical. Es posible que necesitemos encajar un elemento dentro de una altura fija. En esta situación, tenemos otra técnica a nuestra disposición: el desplazamiento horizontal.</p><h2 id="desplazamiento-horizontal-con-desplazamiento-de-desbordamiento">Desplazamiento horizontal con desplazamiento de desbordamiento</h2><p>Puede llegar un momento en que tenga contenido que desborde la ventana gráfica (viewport) sin una forma elegante de manejarlo. He aquí... ¿Overflow scroll al rescate?</p><p>Los usos comunes de esta técnica incluyen tablas y menús desplazables. <br>A continuación se muestra un ejemplo de un menú desplazable. </p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;style&gt;
  menu {
    background: #d9d7d5;
    padding: 0.25rem;
    overflow-y: scroll;
    white-space: nowrap;
  }

  span {
    background: #767775;
    color: #ffffff;
    display: inline-block;
    margin: 0.25rem;
    padding: 0.5rem;
  }
&lt;/style&gt;
&lt;menu&gt;
  &lt;span&gt;Responsive Web Design&lt;/span&gt;
  &lt;span&gt;RWD&lt;/span&gt;
  &lt;span&gt;Responsive menu&lt;/span&gt;
  &lt;span&gt;Overflow scroll example&lt;/span&gt;
  &lt;span&gt;This is a lot of content!&lt;/span&gt;
  &lt;span&gt;Yes&lt;/span&gt;
  &lt;span&gt;we&lt;/span&gt;
  &lt;span&gt;have&lt;/span&gt;
  &lt;span&gt;another&lt;/span&gt;
  &lt;span&gt;item&lt;/span&gt;
&lt;/menu&gt;</code></pre><figcaption>Ejemplo de menú de desplazamiento horizontal</figcaption></figure><p>¿¡Cómo hiciste eso!? Hagamos una inmersión más profunda.</p><ul><li><code>overflow-y: scroll</code> es el ingrediente clave de esta receta. Al especificarlo, los elementos hijos desbordarán el eje horizontal con un comportamiento de desplazamiento.</li><li>¡No tan rapido! Aunque puedas pensar que <code><code>overflow-y</code></code> sería suficiente, también tenemos que decirle al navegador que no envuelva los elementos hijos con <code>white-space: nowrap</code></li></ul><p>Ahora que tenemos algunas técnicas de diseño RWD bajo la manga, echemos un vistazo a los elementos que plantean desafíos específicos a su naturaleza visual: imágenes y video.</p><h2 id="im-genes-adaptativas"><strong><strong>Im</strong>á<strong>ge</strong>ne<strong>s</strong> </strong>adaptativas</h2><p>Mediante el uso de atributos de etiquetas de imágenes, podemos acomodar una variedad de dispositivos y resoluciones. A continuación se muestra un ejemplo de una imagen adaptativa.</p><pre><code class="language-html">&lt;style&gt;
  img {
    max-width: 100%;
  }
&lt;/style&gt;

&lt;picture&gt;
  &lt;source type="image/webp" srcset="https://my-image.com/my-image-100.webp 1x, https://my-image.com/my-image-200.webp 2x"&gt;
  &lt;source type="image/png" srcset="https://my-image.com/my-image-100.png 1x, https://my-image.com/my-image-200.png 2x"&gt;
  &lt;img alt="my image" src="https://my-image.com/my-image-200.png" loading="lazy" width="100" height="100"&gt;
&lt;/picture&gt;</code></pre><p>Esto está haciendo muchas cosas. Vamos a desglosarlo:</p><ol><li>Configurando <code>max-width: 100%</code> la imagen se escalará hacia arriba o hacia abajo según el ancho de su contenedor.</li><li>Mediante el uso de una combinación de las etiquetas <code>picture</code>, <code>source</code>, e <code>img</code> en realidad, solo representamos una imagen y solo cargamos la imagen que mejor se ajusta según el dispositivo del usuario.</li><li><strong>WebP</strong> es un formato de imagen moderno que proporciona una compresión superior para imágenes en la web. Utilizando <code>source</code> podemos hacer referencia a una imagen WebP para usarla en navegadores que la admitan, y otra etiqueta <code>source</code> para hacer referencia a una versión PNG de las imágenes que no son compatibles con WebP.</li><li><code>srcset</code> se usa para decirle al navegador qué imagen usar según la resolución del dispositivo.</li><li>Establecemos la <a href="https://web.dev/native-lazy-loading/">carga diferida nativa</a> utilizando el par atributo/valor <code>loading="lazy"</code>.</li></ol><h2 id="v-deo-adaptativo">Vídeo adaptativo</h2><p>El video adaptativo es otro tema que ha inspirado una gran cantidad de artículos y documentación.</p><p>Una estrategia clave para establecer imágenes, videos, iframes y otros elementos adaptativos implica el uso de la relación de aspecto. El cuadro de relación de aspecto no es una técnica nueva y es una herramienta bastante útil para tener bajo la manga como desarrollador web.</p><p><a href="https://css-tricks.com/fluid-width-video/">Este artículo proporciona una demostración sólida</a> sobre cómo lograr videos de ancho "fluido". Echemos un vistazo al código y lo desglosamos.</p><pre><code class="language-html">&lt;style&gt;
  .videoWrapper {
    position: relative;
    padding-bottom: 56.25%; /* 16:9 */
    height: 0;
  }

  .videoWrapper iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
&lt;/style&gt;

&lt;div class="videoWrapper"&gt;
  &lt;!-- Copy &amp; Pasted from YouTube --&gt;
  &lt;iframe width="560" height="349" src="http://www.youtube.com/embed/n_dZNLr2cME?rel=0&amp;hd=1" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;</code></pre><p>En este ejemplo, tenemos un video de YouTube incrustado como un iframe y un contenedor <code>div</code> con la clase <code>videoWrapper</code>. Este código está haciendo mucho... profundicemos.</p><ul><li><code>position: relative</code> en el elemento contenedor permite que los elementos hijos utilicen el posicionamiento absoluto en relación con él.</li><li><code>height: 0</code> combinado con <code>padding-bottom: 56.25%</code> es el ingrediente clave aquí que establece un comportamiento dinámico, imponiendo una relación de aspecto de 16:9.</li><li><code>position: absolute</code>, <code>top: 0</code> y <code>left: 0</code> establecido en el iframe crea un comportamiento en el que el elemento se posiciona absolutamente en relación con su raíz (parent)... pegándolo en la parte superior izquierda.</li><li>Y finalmente, el ancho y la altura del 100% hacen que el elemento secundario, iframe sea el 100% de su raíz. La raíz, <code>.videoWrapper</code> toma el control total de establecer este diseño de relación de aspecto.</li></ul><p>Lo sé... es mucho. Podemos hacer más para que los videos y las imágenes se vean mejor en teléfonos y tabletas. Fomentaría la investigación sobre esos temas de forma independiente además de esto.</p><p>Bien, ahora que somos expertos en diseño web adaptativo, ¿cómo podemos probar lo que hemos hecho? Afortunadamente, tenemos varias herramientas para simular y monitorizar la experiencia del usuario en una variedad de dispositivos.</p><h2 id="herramientas-para-simular-y-monitorizar-sitios-web-adaptativos">Herramientas para simular y monitorizar sitios web adaptativos</h2><p>Hay una variedad de herramientas útiles para ayudarnos a crear sitios web con un diseño web adaptativo. A continuación hay un par que me parecen especialmente útiles.</p><h3 id="emulaci-n-m-vil-de-chrome-devtools">Emulación móvil de Chrome DevTools</h3><p>Chrome's DevTools proporciona emulación móvil de una variedad de tabletas y dispositivos móviles. También proporciona una opción &nbsp;"adaptativo" que te permite definir un tamaño de ventana (viewport) de visualización personalizado.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/07/Screen-Shot-2020-07-12-at-6.19.18-PM.png" class="kg-image" alt="Screen-Shot-2020-07-12-at-6.19.18-PM" width="600" height="400" loading="lazy"><figcaption>Figura 3: Emulación de dispositivos móviles y tabletas con Chrome DevTools</figcaption></figure><h3 id="monitorizaci-n-del-rendimiento-del-sitio-web-m-vil-con-foo">Monitorización del rendimiento del sitio web móvil con Foo</h3><p>Lighthouse es una herramienta de código abierto que proporciona una forma de analizar el rendimiento del sitio web específico para un dispositivo.</p><p><a href="https://www.foo.software/lighthouse/">Foo usa Lighthouse en segundo plano para monitorizar el rendimiento del sitio web y proporciona comentarios para el análisis.</a> Puedes configura la monitorización para dispositivos móviles y de escritorio para obtener comentarios continuos sobre la capacidad de respuesta de tu sitio web.</p><p>Por ejemplo, un informe de Lighthouse destacará las imágenes que se cargaron incorrectamente según el dispositivo.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/07/Screen-Shot-2020-07-12-at-6.31.09-PM.png" class="kg-image" alt="Screen-Shot-2020-07-12-at-6.31.09-PM" width="600" height="400" loading="lazy"><figcaption>Figura 4: Informe Lighthouse con emulación de dispositivo móvil</figcaption></figure><h2 id="conclusi-n">Conclusión</h2><p>El diseño web adaptativo continuará evolucionando rápidamente, pero si nos mantenemos al tanto de las tendencias actuales, podemos brindar la mejor experiencia a nuestros usuarios. ¡Espero que estas herramientas y técnicas sean útiles!</p><p>Los usuarios de nuestro sitio web no solo se beneficiarán de un diseño versátil, sino que también los motores de búsqueda clasificarán nuestras páginas web más alto.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Visual Studio Code Live Server no funciona ]]>
                </title>
                <description>
                    <![CDATA[ VSCode tiene muchas extensiones excelentes y Live Server [https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer] es una de las mejores. Con solo unos pocos clics, Live Server te permite ver tu página en vivo en un navegador real. Mejor aún, cuenta con recarga en vivo, por lo que si actualizas tu código, los cambios también se ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/visual-studio-code-live-server-no-funciona/</link>
                <guid isPermaLink="false">641e25b2083d0a0781fde39a</guid>
                
                    <category>
                        <![CDATA[ visual studio code ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Mon, 03 Apr 2023 19:30:44 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/03/5f9c9941740569d1a4ca1eab.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/visual-studio-code-live-server-not-working/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Visual Studio Code Live Server Not Working</a>
      </p><p>VSCode tiene muchas extensiones excelentes y <a href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer">Live Server</a> es una de las mejores.</p><p>Con solo unos pocos clics, Live Server te permite ver tu página en vivo en un navegador real. Mejor aún, cuenta con recarga en vivo, por lo que si actualizas tu código, los cambios también se reflejan en el navegador.</p><p>Todo lo que tienes que hacer es hacer clic con el botón derecho en el archivo HTML que deseas ver, botón derecho y luego seleccionar "Abrir con Live Server":</p><p>Pero, ¿qué sucede si el Live Server no abre tu navegador y no muestra tu página como esperabas? Si esto te sucede, aquí hay algunas cosas que puedes probar.</p><h2 id="reiniciar-vsccode">Reiniciar VSCCode</h2><p>A veces, lo mejor que puedes hacer es iniciar VSCode desde cero.</p><p>Primero, guarda todo tu trabajo. Luego cierra VSCode, que también detendrá todas las extensiones que hayas instalado.</p><p>Luego, vuelve a abrir VSCode e intenta nuevamente: Ves al archivo HTML que deseas ver, haz clic con el botón derecho y selecciona "Abrir con Live Server".</p><h2 id="configurar-el-navegador-para-live-server">Configurar el navegador para Live Server</h2><p>Es posible que la extensión esté funcionando, pero que tu sistema no tenga un navegador predeterminado.</p><p>Incluso si configuraste el navegador predeterminado para tu sistema, no estaría de más que Live Server supiera qué navegador te gustaría usar explícitamente.</p><p>Primero, abre la paleta de comandos con F1, luego escribe <code>Preferences: Open Settings (JSON)</code> y seleccione esa opción.</p><p>Esto abrirá tu archivo <code>settings.json</code>.</p><p>Desplázate hasta el final del archivo, agrega una coma después de la última configuración y luego pega lo siguiente <code>"liveServer.settings.CustomBrowser": "chrome"</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2020/09/settings-json.gif" class="kg-image" alt="settings-json" width="600" height="400" loading="lazy"></figure><p>Ten en cuenta que también puedes utilizar <code>"firefox"</code>, <code>"safari"</code>, o cualquier otro navegador como valor para la configuración de <code>"liveServer.settings.CustomBrowser"</code>.</p><p>Finalmente, guarda el archivo <code>settings.json</code> e intenta ejecutar Live Server otra vez.</p><h2 id="configura-el-navegador-predeterminado-para-tu-sistema-operativo">Configura el navegador predeterminado para tu sistema operativo</h2><p>Incluso después de decirle a Live Server qué navegador deseas usar, es posible que todavía no abra tu página en ese navegador correctamente.</p><p>Lo siguiente que debes intentar es configurar el navegador predeterminado para tu propio sistema operativo.</p><p>El método exacto para hacer esto puede variar según tu sistema operativo, por lo que es mejor buscar cómo hacerlo si no estás seguro.</p><p>Así es como se ve la página de configuración en Windows:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/espanol/news/content/images/2023/03/aplicaiones-predeterminadas-por-protocolo.png" class="kg-image" alt="image-56" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2023/03/aplicaiones-predeterminadas-por-protocolo.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2023/03/aplicaiones-predeterminadas-por-protocolo.png 788w" sizes="(min-width: 720px) 720px" width="788" height="604" loading="lazy"><figcaption>Credit: <a href="https://forum.freecodecamp.org/u/Advitya-sharma" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Advitya-sharma</a></figcaption></figure><h2 id="ve-a-la-p-gina-en-vivo-t-mismo">Ve a la página en vivo tú mismo</h2><p>Si por alguna razón Live Server todavía no abre la página en tu navegador automáticamente, no te preocupes. Siempre puedes abrir el navegador de tu elección y ver la página directamente.</p><p>Simplemente, abre tu navegador preferido y ve a &nbsp;<code>http://127.0.0.1:5500/&lt;tu_archivo_html&gt;</code>. </p><p>Por ejemplo, si tu archivo se llama <code>index.html</code>, ves a <code>http://127.0.0.1:5500/index.html</code>. </p><p>Mientras Live Server se esté ejecutando, deberías ver tu página.</p><h2 id="para-concluir">Para concluir</h2><p>Esas son algunas soluciones comunes que puedes probar si Live Server no funciona de la manera esperada.</p><p>Feliz programación y disfruta de la codificación (en directo).</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Color de fuente CSS - Cómo aplicar estilo al texto en HTML ]]>
                </title>
                <description>
                    <![CDATA[ Establecer el color del texto en un sitio web que estás creando puede resultar confuso al principio. Pero en este artículo, aprenderás cómo hacerlo. Cómo establecer el color del texto en HTML En CSS, la propiedad background-color es bastante sencilla para establecer el color de fondo de cualquier cosa. Entonces, ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/color-de-fuente-css-como-aplicar-estilo-al-texto-en-html/</link>
                <guid isPermaLink="false">641cae8655e3ad15a8937026</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Mon, 27 Mar 2023 18:36:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/03/Cssfontcolor.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/css-font-color-how-to-style-text-in-html/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">CSS Font Color – How to Style Text in HTML</a>
      </p><p>Establecer el color del texto en un sitio web que estás creando puede resultar confuso al principio. Pero en este artículo, aprenderás cómo hacerlo.</p><h2 id="c-mo-establecer-el-color-del-texto-en-html">Cómo establecer el color del texto en HTML</h2><p>En CSS, la propiedad <code>background-color</code> es bastante sencilla para establecer el color de fondo de cualquier cosa.</p><p>Entonces, ¿Qué sucede si deseas establecer el color de primer plano de algo en la página? Especialmente el texto, para el que en condiciones normales no querrías establecer un color de fondo.</p><p>No hay una propiedad de <code>foreground-color</code> en CSS, por lo que hace que esto sea posible es la propiedad <code>color</code>.</p><p>En este artículo, te guiaré a través de cómo configurar el color del texto usando la propiedad color. También veremos las diversas formas en que toma valores.</p><p>La propiedad color toma valores de 4 maneras diferentes: Color con nombre, color hexadecimal, color RGB y color HSL. Veamos cada uno ahora.</p><h2 id="colores-con-nombre">Colores con nombre</h2><p>Como su nombre indica, ingresa la propiedad color y aplica el valor nombrando el color deseado. Puede ser rojo, verde, azul, naranja, carmesí, cian o cualquier otro color con nombre. Hay alrededor de 147 colores con nombre reconocidos por los navegadores.</p><p>La sintaxis básica se ve así:</p><pre><code class="language-css">element {
    color: nombreColor
}
</code></pre><pre><code class="language-html">&lt;p&gt;freeCodeCamp&lt;/p&gt;
</code></pre><pre><code class="language-css"> p {
     color: crimson;
}
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/09/named-color.png" class="kg-image" alt="named-color" width="600" height="400" loading="lazy"></figure><h2 id="colores-hexadecimales-o-s-lo-colores-hex-">Colores hexadecimales (O sólo colores Hex)</h2><p>Los valores hexadecimales se utilizan para representar colores con un total de 6 caracteres. Comienzan con el signo almohadilla/número (#), luego cualquier número del 0 al 9 y finalmente cualquier letra de la A a la F.</p><p>Los 2 primeros valores representan el rojo, los dos siguientes representan el verde y los 2 últimos representan el azul. Con valores hexadecimales, no hay límite para los tonos de colores que puedes usar.</p><pre><code class="language-html">&lt;p&gt;freeCodeCamp&lt;/p&gt;
</code></pre><pre><code class="language-css"> p {
    color: #dc143c;
 }
</code></pre><h2 id="colores-rgb">Colores RGB</h2><p>RGB significa rojo, verde y azul. Con RGB, especificas el color en términos de la cantidad de rojo, verde y azul deseados. Los tres se expresan con números entre 0 y 255.</p><p>Hay un tipo de RGB llamado <code>rgba</code>. La 'a' adicional significa alfa, lo que permite especificar la opacidad del color. Toma un valor de 0,0 a 1,0: 0,0 significa 0 % de opacidad, 0,5 significa 50 % de opacidad y 1,0 significa 100 % de opacidad.</p><p>La sintaxis básica es <code>rgba(cantidadDeRojo, cantidadDeVerde, cantidadDeAzul, alfa)</code>. </p><p>Puedes limitarlo a <code>rgba(cantidadDeRojo, cantidadDeVerde, cantidadDeAzul)</code> si no deseas un valor alfa.</p><p>Aquí está la sintaxis de los valores RGB regulares:</p><pre><code class="language-html">&lt;p&gt;freeCodeCamp&lt;/p&gt;
</code></pre><pre><code class="language-css"> p {
   color: rgb(220, 20, 60);
 }
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/09/rgb-color.png" class="kg-image" alt="rgb-color" width="600" height="400" loading="lazy"></figure><p>Y aquí está demostrando el valor alfa en acción con un 50 % (0,5) de opacidad:</p><pre><code class="language-css">p {
    color: rgb(219, 20, 60, 0.5);
}
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/09/rgb-fifty-percent-opacity.png" class="kg-image" alt="rgb-fifty-percent-opacity" width="600" height="400" loading="lazy"></figure><h2 id="colores-hsl">Colores HSL</h2><p>HSL significa tono, saturación y luminosidad. Es otra forma de especificar el color del texto (y cualquier otra cosa que tome color) en CSS.</p><ul><li>Hue representa la rueda de color en 360°. Entonces, 0° es rojo, 120° es verde y 240° es azul. </li><li>La saturación es la cantidad de gris en el color, expresada como un porcentaje. 0% es el tono de gris y 100% es el color en sí. </li><li>La luminosidad es la cantidad de oscuridad y luminosidad en el color expresada como porcentaje. 0% es negro y 100% es blanco.</li></ul><p>Al igual que con los colores RGB, también puedes establecer la opacidad del color. Entonces, también está hsla.</p><p>La sintaxis básica completa es <code>hsl(GradoColor, PorcentajeSaturación, PorcentajeLuminosidad, alfa)</code>. Puedes limitarlo a <code>hsl(GradoColor, PorcentajeSaturación, PorcentajeLuminosidad)</code> en caso de que no desees un valor alfa.</p><pre><code class="language-html">&lt;p&gt;freeCodeCamp&lt;/p&gt;
</code></pre><pre><code class="language-css"> p {
   color: hsl(348, 83%, 47%);
 }
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/09/hsl-color.png" class="kg-image" alt="hsl-color" width="600" height="400" loading="lazy"></figure><p>Puedes aplicar una opacidad particular al color hsl como este:</p><pre><code class="language-css"> p {
   color: hsla(348, 83%, 47%, 0.5);
  }
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/09/hsl-fifty-percent-opacity-1.png" class="kg-image" alt="hsl-fifty-percent-opacity-1" width="600" height="400" loading="lazy"></figure><h2 id="-debes-utilizar-colores-con-nombre-colores-hexadecimales-colores-rgb-o-colores-hsl-para-asignar-colores">¿Debes utilizar colores con nombre, colores hexadecimales, colores RGB o colores HSL para asignar colores?</h2><p>Una de las cosas maravillosas de CSS es que hay múltiples formas de hacer lo mismo. Has visto esto al aplicar colores al texto.</p><p>Dado que puedes aplicar colores de 4 maneras diferentes, debes preguntarte cuál es la mejor para usar.</p><p>Cuando usas colores con nombre, estás un poco limitado en cuanto a cuán lejos puedes llegar al aplicar diferentes tonos de colores. El rojo, el verde, el azul, el amarillo o cualquier otro color con nombre tiene muchas variaciones a las que no tendrás acceso con los colores con nombre. Solo tendrás acceso a alrededor de 147 colores predefinidos reconocidos por los navegadores.</p><p>Los colores hexadecimales son muy dinámicos. Son los más utilizados entre los desarrolladores porque el límite es tu creatividad. Con los colores hexadecimales, puedes usar varios tonos e incluso usar un color que nadie haya usado nunca.</p><p>Los colores RGB son tan dinámicos como los colores hexadecimales. Además de poder especificar cuánto rojo, verde y azul deseas de 0 a 255, también puedes establecer qué tan transparente deseas que sea el color con el valor alfa adicional.</p><p>HSL es el más dinámico de todos. Puedes especificar el color exacto que deseas en grados de 0 a 360 dentro de la rueda de colores, establecer qué tan saturado y oscuro deseas que sea en porcentajes, y también establecer una opacidad de 0.0 a 1.0.</p><p>Realmente, depende de ti, del uso que le quieras dar y de cuán creativo o específico quieras ser.</p><h2 id="conclusi-n">Conclusión</h2><p>La aplicación de colores al texto ayuda a que tu sitio web sea más atractivo para los visitantes. La combinación de colores correcta también puede ayudarte a que el contenido sea más legible.</p><p>En este artículo, has aprendido cómo aplicar colores al texto con los 4 tipos diferentes de valores que puedes usar con la propiedad de color.</p><p>Gracias por leer, y sigue programando.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Lista HTML: Cómo usar viñetas, listas ordenadas y desordenadas ]]>
                </title>
                <description>
                    <![CDATA[ Enumerar elementos en una página web es una tarea común que deberás realizar como desarrollador web. Es posible que debas enumerar los artículos del carrito de compras, el orden de los estudiantes según sus calificaciones, los perros con los ladridos más fuertes, etc. Por lo tanto, debes conocer las diferentes ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/lista-html-como-usar-vinetas-listas-ordenadas-y-desordenadas/</link>
                <guid isPermaLink="false">6419fc3655e3ad15a893676a</guid>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ BlackeyeB ]]>
                </dc:creator>
                <pubDate>Sat, 25 Mar 2023 00:56:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/03/freeCodeCamp-Cover-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/html-list-how-to-use-bullet-points-ordered-and-unordered-lists/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">HTML List – How to Use Bullet Points, Ordered, and Unordered Lists</a>
      </p><p>Enumerar elementos en una página web es una tarea común que deberás realizar como desarrollador web. Es posible que debas enumerar los artículos del carrito de compras, el orden de los estudiantes según sus calificaciones, los perros con los ladridos más fuertes, etc.</p><p>Por lo tanto, debes conocer las diferentes formas en que puedes enumerar elementos usando HTML. Si bien puedes pensar que es algo trivial de aprender, es importante. Y es una de las características más utilizadas de HTML en el desarrollo web.</p><p>En este artículo, aprenderás todo acerca de los elementos de listas HTML, sus propiedades, estilos y cómo usarlos para crear listas ordenadas. Espero que te sea útil.</p><h1 id="c-mo-hacer-listas-en-html">Cómo hacer listas en HTML</h1><p>En HTML, podemos enumerar elementos en forma ordenada o desordenada.</p><p>Una lista ordenada utiliza números o algún tipo de notación que indica una serie de elementos.</p><p>Por ejemplo, una lista ordenada puede comenzar con el número 1 y continuar por el 2, 3, 4, etc. Tu lista ordenada también puede comenzar con la letra A y pasar por B, C, D, etc.</p><p>Aquí hay un ejemplo de una lista ordenada con los nombres y calificaciones de los estudiantes.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/07/ordered-1.png" class="kg-image" alt="ordered-1" width="600" height="400" loading="lazy"><figcaption>lista ordenada de alumnos</figcaption></figure><p>Por otro lado, tenemos listas desordenadas, como una lista de tareas, por ejemplo. Soy tan apasionado por la programación que me salté el desayuno ?.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/07/unordered-1.png" class="kg-image" alt="unordered-1" width="600" height="400" loading="lazy"><figcaption>Lista de tareas desordenada</figcaption></figure><p>Hay un tipo más de lista llamada <code>lista de descripción</code> &nbsp;que también aprenderemos a continuación.</p><p>Ahora entremos un poco más en detalle y veamos cómo crear cada tipo de lista en HTML.</p><h1 id="c-mo-hacer-una-lista-ordenada-con-html">Cómo hacer una lista ordenada con HTML</h1><p>En HTML, podemos crear una lista ordenada usando la etiqueta &nbsp;<code>&lt;ol&gt;</code>. La etiqueta <code>ol</code> representa una lista ordenada. Dentro de cada uno de los elementos de la lista ordenada <code>&lt;ol&gt;</code> y <code>&lt;ol /&gt;</code>, tenemos que definir los elementos de la lista. Podemos definir los elementos de la lista usando la etiqueta <code>&lt;li&gt;</code>.</p><p>Aquí está la estructura HTML completa para una lista ordenada:</p><pre><code class="language-html">&lt;ol&gt;
  &lt;li&gt;Eat&lt;/li&gt;
  &lt;li&gt;Code&lt;/li&gt;
  &lt;li&gt;Sleep&lt;/li&gt;
&lt;/ol&gt;</code></pre><p>El resultado de la lista ordenada anterior es:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/07/image.png" class="kg-image" alt="image" width="600" height="400" loading="lazy"></figure><p>Entonces, tenemos la lista de elementos ordenados con un número que comienza con 1 y se incrementa a 2 y 3. Pruebe este CodePen y vea si puede cambiar y jugar usando <code>ol-li</code>.</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe id="cp_embed_gOWpbMK" src="https://codepen.io/atapas/embed/preview/gOWpbMK?default-tabs=html%2Cresult&amp;height=300&amp;host=https%3A%2F%2Fcodepen.io&amp;slug-hash=gOWpbMK" title="Embedded content" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; width: 720px; overflow: hidden;"></iframe><figcaption>ordered list of items</figcaption></figure><h3 id="tipos-de-listas-ordenadas-en-html"><strong>Tipos de listas ordenadas en HTML</strong></h3><p>¿Qué pasa si no quieres ordenar tu lista por número? En su lugar, deseas ordenar usando el alfabeto como A, B, C o a, b, c. Puedes hacerlo especificando el valor del atributo <code>type</code> de la etiqueta <code>&lt;ol&gt;</code>.</p><p>Puedes ordenar la lista usando las letras A, B, C pasando <code>A</code> como valor de type(tipo).</p><pre><code class="language-html">&lt;ol type="A"&gt;
  &lt;li&gt;Eat&lt;/li&gt;
  &lt;li&gt;Code&lt;/li&gt;
  &lt;li&gt;Sleep&lt;/li&gt;
&lt;/ol&gt;</code></pre><p>La salida se ve así:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/07/image-10.png" class="kg-image" alt="image-10" width="600" height="400" loading="lazy"></figure><p>De manera similar, puedes usar letras minúsculas como <code>a</code> para el valor del tipo y así enumerar los elementos con a, b, c, etc.</p><pre><code class="language-html">&lt;ol type="a"&gt;
  &lt;li&gt;Eat&lt;/li&gt;
  &lt;li&gt;Code&lt;/li&gt;
  &lt;li&gt;Sleep&lt;/li&gt;
&lt;/ol&gt;</code></pre><p>Aquí está la salida:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/07/image-2.png" class="kg-image" alt="image-2" width="600" height="400" loading="lazy"></figure><p>Si desea utilizar números romanos, utilice el valor <code>I</code> para una lista ordenada con números romanos:</p><pre><code class="language-html">&lt;ol type="I"&gt;
  &lt;li&gt;Eat&lt;/li&gt;
  &lt;li&gt;Code&lt;/li&gt;
  &lt;li&gt;Sleep&lt;/li&gt;
&lt;/ol&gt;</code></pre><p>La salida se ve así:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/07/image-3.png" class="kg-image" alt="image-3" width="600" height="400" loading="lazy"></figure><p>Consulte el CodePen a continuación para probar otros tipos:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe id="cp_embed_LYyVEbL" src="https://codepen.io/atapas/embed/preview/LYyVEbL?default-tabs=html%2Cresult&amp;height=300&amp;host=https%3A%2F%2Fcodepen.io&amp;slug-hash=LYyVEbL" title="Embedded content" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; width: 720px; overflow: hidden;"></iframe><figcaption>Tipos de listas ordenadas</figcaption></figure><h2 id="c-mo-usar-el-atributo-start-en-listas-html">Cómo usar el atributo start en listas HTML</h2><p>El elemento <code>&lt;ol&gt;</code> tiene un atributo interesante llamado <code>start</code>. Puedes especificar un valor del atributo de inicio ("start") para iniciar la lista ordenada desde un número específico.</p><p>Digamos que deseas comenzar la lista con el número <code>30</code> en lugar de <code>1</code>. Puedes especificar el número <code>30</code> como el valor del atributo <code>start</code> de esta manera:</p><pre><code class="language-html">&lt;ol start="30"&gt;
  &lt;li&gt;Thirty&lt;/li&gt;
  &lt;li&gt;Thirty One&lt;/li&gt;
  &lt;li&gt;Thirty Two&lt;/li&gt;
&lt;/ol&gt;</code></pre><p>La salida se ve así:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/07/image-4.png" class="kg-image" alt="image-4" width="600" height="400" loading="lazy"></figure><p>Siéntete libre de jugar con el atributo <code>start</code> usando este CodePen:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe id="cp_embed_VwbLYzQ" src="https://codepen.io/atapas/embed/preview/VwbLYzQ?default-tabs=html%2Cresult&amp;height=300&amp;host=https%3A%2F%2Fcodepen.io&amp;slug-hash=VwbLYzQ" title="Embedded content" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; width: 720px; overflow: hidden;"></iframe><figcaption>start attribute</figcaption></figure><p>Por cierto, he compartido los mismos consejos en Twitter recientemente. También puedes encontrar una discusión interesante allí:</p><figure class="kg-card kg-embed-card"><iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true" class="" title="Twitter Tweet" src="https://platform.twitter.com/embed/Tweet.html?creatorScreenName=tapasadhikary&amp;dnt=false&amp;embedId=twitter-widget-0&amp;features=eyJ0ZndfdGltZWxpbmVfbGlzdCI6eyJidWNrZXQiOltdLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X2ZvbGxvd2VyX2NvdW50X3N1bnNldCI6eyJidWNrZXQiOnRydWUsInZlcnNpb24iOm51bGx9LCJ0ZndfdHdlZXRfZWRpdF9iYWNrZW5kIjp7ImJ1Y2tldCI6Im9uIiwidmVyc2lvbiI6bnVsbH0sInRmd19yZWZzcmNfc2Vzc2lvbiI6eyJidWNrZXQiOiJvbiIsInZlcnNpb24iOm51bGx9LCJ0ZndfbWl4ZWRfbWVkaWFfMTU4OTciOnsiYnVja2V0IjoidHJlYXRtZW50IiwidmVyc2lvbiI6bnVsbH0sInRmd19leHBlcmltZW50c19jb29raWVfZXhwaXJhdGlvbiI6eyJidWNrZXQiOjEyMDk2MDAsInZlcnNpb24iOm51bGx9LCJ0ZndfZHVwbGljYXRlX3NjcmliZXNfdG9fc2V0dGluZ3MiOnsiYnVja2V0Ijoib24iLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X3ZpZGVvX2hsc19keW5hbWljX21hbmlmZXN0c18xNTA4MiI6eyJidWNrZXQiOiJ0cnVlX2JpdHJhdGUiLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X2xlZ2FjeV90aW1lbGluZV9zdW5zZXQiOnsiYnVja2V0Ijp0cnVlLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X3R3ZWV0X2VkaXRfZnJvbnRlbmQiOnsiYnVja2V0Ijoib24iLCJ2ZXJzaW9uIjpudWxsfX0%3D&amp;frame=false&amp;hideCard=false&amp;hideThread=false&amp;id=1410508936344588289&amp;lang=en&amp;origin=https%3A%2F%2Fwww.freecodecamp.org%2Fnews%2Fhtml-list-how-to-use-bullet-points-ordered-and-unordered-lists%2F&amp;sessionId=0f8696baaf62292959b838894cf3cd4e58022e5f&amp;siteScreenName=freecodecamp&amp;theme=light&amp;widgetsVersion=aaf4084522e3a%3A1674595607486&amp;width=550px" data-tweet-id="1410508936344588289" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; position: static; visibility: visible; width: 550px; height: 1018px; display: block; flex-grow: 1;" loading="lazy"></iframe></figure><h1 id="c-mo-hacer-una-lista-desordenada-en-html">Cómo hacer una lista desordenada en HTML</h1><p>Pasemos ahora a las listas desordenadas. Usamos la etiqueta <code>&lt;ul&gt;</code> para crear una lista desordenada. Como de costumbre, necesitamos usar las etiquetas <code>&lt;li&gt;</code> dentro de <code>&lt;ul&gt;</code> y <code>&lt;ul/&gt;</code> para crear los elementos de la lista.</p><p>Los elementos de la lista (<code>li</code>) dentro de la lista desordenada (<code>ul</code>) vienen con el estilo predeterminado de viñetas, por lo que cada uno de los elementos de la lista está precedido por un punto negro.</p><p>Vamos a crear una lista de mis recursos en línea favoritos para aprender sobre programación web:</p><pre><code class="language-html">My Favorite Web Development Learning Sites
&lt;!-- Mis sitios favoritos de aprendizaje sobre desarrollo web --&gt;
&lt;div&gt;
  &lt;ul&gt;
    &lt;li&gt;freeCodeCamp&lt;/li&gt;
    &lt;li&gt;CSS-Tricks&lt;/li&gt;
    &lt;li&gt;Traversy Media&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;</code></pre><p>La salida se ve así:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/07/image-5.png" class="kg-image" alt="image-5" width="600" height="400" loading="lazy"><figcaption>Mis sitios favoritos de aprendizaje sobre desarrollo web</figcaption></figure><p>Puedes ver las viñetas de cada uno de los elementos de la lista anterior y puedes personalizarlos. Eso también lo aprenderemos.</p><p>Pero antes de eso, siéntete libre de usar este CodePen para cambiar y ejecutar el código.</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe id="cp_embed_zYwxgJw" src="https://codepen.io/atapas/embed/preview/zYwxgJw?default-tabs=html%2Cresult&amp;height=300&amp;host=https%3A%2F%2Fcodepen.io&amp;slug-hash=zYwxgJw" title="Embedded content" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; width: 720px; overflow: hidden;"></iframe><figcaption>viñetas</figcaption></figure><h2 id="c-mo-usar-vi-etas-con-enlaces-en-listas-html">Cómo usar viñetas con enlaces en listas HTML</h2><p>Podemos usar los enlaces (etiqueta de anclaje <code>&lt;a&gt;</code>) en los elementos de la lista (etiqueta <code>&lt;li&gt;</code>) para vincular cada uno de los elementos a cualquier página web interna o externa.</p><p>Aquí hay un ejemplo que te muestra cómo vincular cada uno de los recursos de programación web a sus respectivos sitios web:</p><pre><code class="language-html">My Favorite Web Development Learning Sites
&lt;!-- Mis sitios favoritos de aprendizaje sobre desarrollo web --&gt;
&lt;div&gt;
  &lt;ul&gt;
    &lt;li&gt;
      &lt;a href="https://www.freecodecamp.org/" target="_blank"&gt;freeCodeCamp&lt;/a&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;a href="https://css-tricks.com/" target="_blank"&gt;CSS-Tricks&lt;/a&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;a href="https://www.traversymedia.com/" target="_blank"&gt;Traversy Media&lt;/a&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;</code></pre><p>La salida se ve así:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/07/image-6.png" class="kg-image" alt="image-6" width="600" height="400" loading="lazy"><figcaption>Mis sitios favoritos de aprendizaje sobre desarrollo web</figcaption></figure><p>Puedes usar CodePen a continuación para probar lo mismo. Siéntete libre de modificarlo como desees:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe id="cp_embed_yLbNBmj" src="https://codepen.io/atapas/embed/preview/yLbNBmj?default-tabs=html%2Cresult&amp;height=300&amp;host=https%3A%2F%2Fcodepen.io&amp;slug-hash=yLbNBmj" title="Embedded content" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; width: 720px; overflow: hidden;"></iframe><figcaption>bullet points with links viñetas con enlaces</figcaption></figure><h2 id="tipos-de-listas-desordenadas-en-html">Tipos de listas desordenadas en HTML</h2><p>Como discutimos brevemente, podemos personalizar el estilo de viñetas de una lista desordenada, que veremos en acción ahora. Podemos hacer esto usando la propiedad de estilo CSS llamada <code>list-style</code>.</p><p>Hay cuatro valores principales de la propiedad <code>list-style</code> que nos ayudan con esta personalización:</p><!--kg-card-begin: html--><table style="box-sizing: inherit; margin: 0.5em 0px 2.5em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, Oxygen, Ubuntu, Cantarell, &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, sans-serif; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 1.6rem; vertical-align: top; border-spacing: 0px; border-collapse: collapse; display: inline-block; overflow-x: auto; max-width: 100%; width: auto; white-space: nowrap; background: radial-gradient(at left center, rgba(0, 0, 0, 0.2) 0px, rgba(0, 0, 0, 0) 75%) 0px center / 10px 100% no-repeat scroll, radial-gradient(at right center, rgba(0, 0, 0, 0.2) 0px, rgba(0, 0, 0, 0) 75%) 100% center / 10px 100% scroll rgb(255, 255, 255); color: rgb(10, 10, 35); letter-spacing: normal; orphans: 2; text-align: start; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><thead style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><th style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: 700; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 1.2rem; vertical-align: baseline; color: var(--gray85); letter-spacing: 0.2px; text-align: left; text-transform: uppercase; background-color: var(--gray10);">LIST-STYLE</th><th style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: 700; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 1.2rem; vertical-align: baseline; color: var(--gray85); letter-spacing: 0.2px; text-align: right; text-transform: uppercase; background-color: var(--gray10);">EFECTO</th></tr></thead><tbody style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(255, 255, 255) 50%, rgba(255, 255, 255, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">none</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(255, 255, 255) 50%, rgba(255, 255, 255, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat; text-align: right;">No aparecerá ninguna viñeta delante del elemento de la lista</td></tr><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(255, 255, 255) 50%, rgba(255, 255, 255, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">circle</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(255, 255, 255) 50%, rgba(255, 255, 255, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat; text-align: right;">Aparece una viñeta circular (hueca) delante del elemento de la lista</td></tr><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(255, 255, 255) 50%, rgba(255, 255, 255, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">disc</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(255, 255, 255) 50%, rgba(255, 255, 255, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat; text-align: right;">Esta es la viñeta circular rellena predeterminada</td></tr><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(255, 255, 255) 50%, rgba(255, 255, 255, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">square</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(255, 255, 255) 50%, rgba(255, 255, 255, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat; text-align: right;">Aparece una viñeta cuadrada rellena delante del elemento de la lista</td></tr></tbody></table><!--kg-card-end: html--><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe id="cp_embed_vYmOYyK" src="https://codepen.io/atapas/embed/preview/vYmOYyK?default-tabs=html%2Cresult&amp;height=300&amp;host=https%3A%2F%2Fcodepen.io&amp;slug-hash=vYmOYyK" title="Embedded content" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; width: 720px; overflow: hidden;"></iframe><figcaption>unordered list styles estilos de lista desordenada</figcaption></figure><p>Puede usar el CodePen anterior para probar diferentes opciones de <code>list-style</code>.</p><h1 id="-sab-as-que-tambi-n-hay-una-lista-con-descripciones">¿Sabías que también hay una lista con descripciones?</h1><p>Hay un tipo más de lista HTML, pero no se usa con tanta frecuencia. Se llama <code>Description List</code>.</p><p>Podemos definir una lista de descripciones utilizando el elemento de etiqueta <code>&lt;dl&gt;</code>. Dentro de <code>&lt;dl&gt;</code>..<code>&lt;/dl&gt;</code> necesitamos definir un término de descripción usando la etiqueta <code>&lt;dt&gt;</code>. El término suele ser un pequeño texto sobre algo. Luego, podemos definir el descriptor de descripción para describir más el término usando la etiqueta <code>&lt;dd&gt;</code>.</p><p>¿Demasiado para digerir? Veamos cómo funciona con un ejemplo de código.</p><p>Supongamos que queremos describir información sobre programación, chismes y dormir en nuestra página web. Primero podemos definir una etiqueta<code>&lt;dl&gt;</code>. Ahora definimos tres pares de etiquetas <code>&lt;dt&gt;</code> y <code>&lt;dd&gt;</code> para describir la codificación, el chisme y el sueño, respectivamente.</p><pre><code class="language-html">&lt;dl&gt;
  &lt;dt&gt;Coding&lt;/dt&gt;
    &lt;!-- Programación --&gt;
  &lt;dd&gt;An activity to keep you happy, even in sleep.&lt;/dd&gt;
      &lt;!-- Una actividad para mantenerte feliz, incluso mientras duermes. --&gt;
  &lt;dt&gt;Gossiping&lt;/dt&gt;
      &lt;!-- Chismorreo --&gt;
  &lt;dd&gt;Can't live without it.&lt;/dd&gt;
      &lt;!-- No puedo vivir sin el. --&gt;
  &lt;dt&gt;Sleeping&lt;/dt&gt;
      &lt;!-- Dormir --&gt;
  &lt;dd&gt;My all time favorite.&lt;/dd&gt;
      &lt;!-- Mi favorito de todos los tiempos. --&gt;
&lt;/dl&gt;</code></pre><p>La salida se ve así:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/07/image-7.png" class="kg-image" alt="image-7" width="600" height="400" loading="lazy"></figure><p>Prueba este CodePen para experimentar más con las listas con descripción:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe id="cp_embed_xxdGbzL" src="https://codepen.io/atapas/embed/preview/xxdGbzL?default-tabs=html%2Cresult&amp;height=300&amp;host=https%3A%2F%2Fcodepen.io&amp;slug-hash=xxdGbzL" title="Embedded content" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; width: 720px; overflow: hidden;"></iframe><figcaption>description list lista de descripciones</figcaption></figure><p>Te estarás preguntando, ¿por qué no usamos mucho este tipo de lista? Bueno, puedes crear esta estructura utilizando la lista desordenada (ul), elementos de lista (li) y los estilos CSS.</p><p>Pero si consideras la semántica de HTML, debes dar un lugar a las listas de descripción en tu código cuando tengas un buen caso de uso para ello.</p><h1 id="c-mo-crear-un-encabezado-de-p-gina-con-elementos-de-lista-html">Cómo crear un encabezado de página con elementos de lista HTML</h1><p>Estamos casi al final de este tutorial. Pero siento que está incompleto sin al menos un ejemplo de caso de uso de las listas y etiquetas HTML. Mi favorito es enumerar los elementos en el encabezado de una página web.</p><p>Vamos a crear un encabezado muy básico con un logotipo de muestra y tres enlaces:<code>Home</code>, <code>Products</code>, y <code>About Us</code>. Primero crearemos la estructura HTML así:</p><pre><code class="language-html">&lt;nav&gt;
  &lt;span class="logo"&gt;Logo&lt;/span&gt;
  
  &lt;ul&gt;
    &lt;li&gt;&lt;a href="#/home"&gt;Home&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#/products"&gt;Products&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#/about"&gt;About Us&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;  
&lt;/nav&gt;</code></pre><p>Aquí hemos tomado una lista desordenada con tres elementos de lista para definir los enlaces Inicio, Productos y Acerca de nosotros. También notarás un elemento de intervalo con el logotipo de texto que indica que es un logotipo. Podemos usar una imagen adecuada allí, según nuestras necesidades más adelante.</p><p>Hasta ahora, el encabezado debería verse así:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/07/image-8.png" class="kg-image" alt="image-8" width="600" height="400" loading="lazy"></figure><p>Bueno, esto no es lo que queremos. Entonces, a continuación, escribiremos algunas reglas y propiedades de CSS para que se vea como un encabezado de página (al menos algo más parecido).</p><pre><code class="language-css">nav{
  background-color: #273032;
  color: #FFF;
  padding: 10px;
  display: flex;
}

.logo {
  background-color: blue
}

ul {
  margin: 0px;
}

li {
  list-style: none;
  display: inline;
  margin-right: 0.2rem;
}

a {
  color: pink;
}</code></pre><p>Ahora mucho mejor y se parece más a un encabezado de página de verdad.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/07/image-9.png" class="kg-image" alt="image-9" width="600" height="400" loading="lazy"></figure><p>Nuevamente, puedes usar este CodePen para cambiar y probar cosas con el encabezado.</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe id="cp_embed_OJmVPGe" src="https://codepen.io/atapas/embed/preview/OJmVPGe?default-tabs=css%2Cresult&amp;height=300&amp;host=https%3A%2F%2Fcodepen.io&amp;slug-hash=OJmVPGe" title="Embedded content" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" loading="lazy" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 22px; vertical-align: middle; width: 720px; overflow: hidden;"></iframe><figcaption>header</figcaption></figure><h1 id="antes-de-terminar-">Antes de terminar...</h1><p>Eso es todo por ahora. Espero que este artículo te haya resultado útil y que te ayude a comprender las listas HTML con mayor claridad. Puedes encontrar todos los ejemplos juntos en esta <a href="https://codepen.io/collection/jbOYRo?sort_by=item_created_at&amp;grid_type=list">CodePen Collection</a>.</p><p>Conectémonos. Me encontrarás activo en <a href="https://twitter.com/tapasadhikary">Twitter (@tapasadhikary)</a>. Siéntete libre de seguirme. También comencé a compartir conocimientos a través de mi <a href="https://youtube.com/c/TapasAdhikary?sub_confirmation=1">Canal de YouTube</a>, por lo que también puedes consultarlo.</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
