<?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[ Jose González - 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[ Jose González - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/espanol/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 19:37:24 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/espanol/news/author/jose-gonzalez-nunez/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Cómo empezar con Firebase usando Python ]]>
                </title>
                <description>
                    <![CDATA[ Este artículo es una guía detallada que te ayudará a configurar tu base de datos de Firebase y ejecutar simples operaciones de CRUD (Crear, Leer, Actualizar, Borrar) en ella usando Python. Firebase, como podrías saber, es una plataforma de Google para acelerar el desarrollo de apps. Ofrece BaaS o backend ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-empezar-con-firebase-usando-python/</link>
                <guid isPermaLink="false">6302a62349da500911a0ef6b</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jose González ]]>
                </dc:creator>
                <pubDate>Fri, 24 Mar 2023 18:13:41 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2023/03/6015593f0a2838549dcbb3b9.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-get-started-with-firebase-using-python/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Get Started with Firebase Using Python</a>
      </p><p>Este artículo es una guía detallada que te ayudará a configurar tu base de datos de Firebase y ejecutar simples operaciones de CRUD (Crear, Leer, Actualizar, Borrar) en ella usando Python.</p><p>Firebase, como podrías saber, es una plataforma de Google para acelerar el desarrollo de apps. Ofrece BaaS o backend como un servicio, lo cual significa que Firebase se encarga de la infraestructura de la nube y de todas tus necesidades de backend. Esto te permite desarrollar y publicar más rápido.</p><p>Firebase ofrece varios sorprendentes productos, tales como una base de datos en tiempo real, una nube de almacenamiento Firestore, y Autenticación. Y además permite el hosting y ofrece APIs para tareas de machine learning como el reconocimiento de texto, etiquetado de imágenes y ¡mucho más!</p><p>Dale un vistazo al sitio haciendo clic <a href="https://firebase.google.com/">aquí</a> y babea sobre las maravillosas opciones disponibles.</p><h2 id="como-configurar-una-base-de-datos-en-tiempo-real-con-firebase"><strong>Como configurar una base de datos en tiempo real con Firebase</strong></h2><p>Cree un nuevo proyecto en Firebase – Nombrémoslo ProyectoLibrería (o BookstoreProject, en inglés). Una vez creado, se debe crear la base de datos a tiempo real seleccionando la opción crear base de datos (o create Database).</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/01/pic-1.png" class="kg-image" alt="pic-1" width="600" height="400" loading="lazy"><figcaption>Creando una base de datos a tiempo real usando la consola de Firebase</figcaption></figure><p>Cuando haces clic en crear base de datos, debes especificar la ubicación de la base de datos y las reglas de seguridad. Dos reglas están disponibles:</p><ul><li>Modo bloqueado, el cual niega toda lectura o escritura en la base de datos, y</li><li>Modo de prueba, el cual permite el acceso a la lectura y la escritura por 30 días como opción por defecto (después de dicha fecha, todos los accesos a lectura y escritura a la base de datos serán bloqueados a no ser que las reglas de seguridad sean actualizadas).</li></ul><p>Ya que estaremos usando la base de datos para leer, escribir y editar, seleccionamos el modo de prueba. Una vez terminado, la base de datos está lista para su utilización.</p><h2 id="como-escribir-en-la-base-de-datos-en-tiempo-real-de-firebase-usando-python"><strong>Como escribir en la base de datos en tiempo real de Firebase usando Python</strong></h2><p>El inmediato siguiente paso consiste en encontrar como podemos conectarnos a nuestra base de datos usando Python. Vamos a usar la API Admin Database. Requerirás instalar la librería solicitada.</p><p>Para más información en como usar <code>firebase_admin</code> para Python, revisa la documentación oficial <a href="https://firebase.google.com/docs/database/admin/start">aquí</a>.</p><pre><code class="language-python">pip install firebase_admin</code></pre><p>Para conectar con Firebase, necesitamos las siguientes líneas de código:</p><pre><code>import firebase_admin

cred_obj = firebase_admin.credentials.Certificate('....dirección del archivo')
default_app = firebase_admin.initialize_app(cred_object, {
	'databaseURL':databaseURL
	})</code></pre><p>Para hacer que el código funcione, sin embargo, necesitamos de algunos prerrequisitos.</p><p>Primero, necesitamos especificar la dirección a una clave de cuenta de servicio que será usada para inicializar el admin SDK.</p><p>Firebase permitirá el acceso al servidor de APIs de Firebase desde las cuentas de servicio de Google, y para ello requerimos de una clave privada en formato JSON.</p><p>La dirección a este archivo JSON debe ser entregada para crear el objeto de credencial. Para generar la clave, vamos a la configuración del proyecto, haz clic en generar una nueva clave privada, descarga el archivo, y alojarlo en su directorio.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-205.png" class="kg-image" alt="image-205" width="600" height="400" loading="lazy"><figcaption>Ajustes de Proyecto en la consola de Firebase</figcaption></figure><p>Para una explicación mucho más elaborada de este proceso, puedes revisar la documentación oficial <a href="https://firebase.google.com/docs/admin/setup">aquí</a>.</p><p>A continuación, necesitamos la URL de la base de datos, la cual es simplemente la URL que nos da acceso a nuestra base de datos. Está presente en la misma página consola de la base de datos a tiempo real de Firebase.</p><h3 id="como-escribir-con-la-funci-n-set-"><strong>Como escribir con la función set()</strong></h3><pre><code>from firebase_admin import db

ref = db.reference("/")</code></pre><p>Configuramos la referencia a la raíz de la base de datos (o también podemos referenciarla a un valor clave o a un valor clave hijo). La pregunta que naturalmente aparece es, ¿qué esquema está soportado para almacenar datos en las bases de datos de tiempo real?</p><p>Toda la información almacenada debe estar en un formato JSON, esto es, una secuencia de parejas de valores clave. Si necesitas un sistema de claves generadas, podrías optar a utilizar la función <code>push()</code>, la cual cubriremos prontamente.</p><p>Vamos a construir un JSON adecuado para ser guardado en la base de datos. Tenemos información relacionada con libros como sigue:</p><pre><code class="language-json">{
	"Book1":
	{
		"Title": "The Fellowship of the Ring",
		"Author": "J.R.R. Tolkien",
		"Genre": "Epic fantasy",
		"Price": 100
	},
	"Book2":
	{
		"Title": "The Two Towers",
		"Author": "J.R.R. Tolkien",
		"Genre": "Epic fantasy",
		"Price": 100	
	},
	"Book3":
	{
		"Title": "The Return of the King",
		"Author": "J.R.R. Tolkien",
		"Genre": "Epic fantasy",
		"Price": 100
	},
	"Book4":
	{
		"Title": "Brida",
		"Author": "Paulo Coelho",
		"Genre": "Fiction",
		"Price": 100
	}
}</code></pre><p>Cargamos el archivo JSON necesario y guardamos la información en la base de datos de la siguiente manera:</p><pre><code>import json
with open("book_info.json", "r") as f:
	file_contents = json.load(f)
ref.set(file_contents)</code></pre><p>La base de datos ahora debería verse así:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-207.png" class="kg-image" alt="image-207" width="600" height="400" loading="lazy"><figcaption>Esquema de la vista de la base de datos desde la consola de Firebase</figcaption></figure><h3 id="como-escribir-usando-la-funci-n-push-"><strong>Como escribir usando la función push()</strong></h3><p>Firebase nos entrega la función <code>push()</code> que guarda información bajo un sistema de generación de claves únicas. Este método asegura que si múltiples escrituras se están realizando bajo la misma clave, no se sobreescriban entre sí.</p><p>Por ejemplo, si múltiples fuentes tratan de escribir en /Books/Best_Sellers/ entonces, quien sea que haya realizado la última escritura o carga, dicha información es la que quedará registrada en la base de datos. Esto agrega la posibilidad de que la información puede ser sobreescrita.<code>push()</code> resuelve este problema al usar una clave única para cada hijo que sea agregado.</p><pre><code>ref = db.reference("/")
ref.set({
	"Books":
	{
		"Best_Sellers": -1
	}
})

ref = db.reference("/Books/Best_Sellers")
import json
with open("book_info.json", "r") as f:
	file_contents = json.load(f)

for key, value in file_contents.items():
	ref.push().set(value)</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-208.png" class="kg-image" alt="image-208" width="600" height="400" loading="lazy"><figcaption>Esquema de la base de datos después de ejecutar el método push()</figcaption></figure><p>Por favor, note que <code>push()</code> y <code>set()</code> no son atómicos. Es decir, no hay ninguna garantía de que ambas funciones se ejecutarán juntas sin interrupción como una única unidad indivisible.</p><p>Mientras la base de datos está siendo actualizada, si intentamos obtener la información, puede suceder que <code>push()</code> haya finalizado, pero <code>set()</code> no lo haya hecho aún – por lo que el JSON que recibiremos tendrá una clave generada por el sistema sin un valor.</p><h2 id="como-actualizar-tu-base-de-datos-firebase-usando-python"><strong>Como actualizar tu base de datos Firebase usando Python</strong></h2><p>Actualizar la base de datos es tan simple como configurar la referencia en el punto requerido y usar la función <code>update()</code>. Digamos que el precio de los libros de J. R. R. Tolkien se han reducido a 80 unidades parar ofrecer un descuento.</p><pre><code>ref = db.reference("/Books/Best_Sellers/")
best_sellers = ref.get()
print(best_sellers)
for key, value in best_sellers.items():
	if(value["Author"] == "J.R.R. Tolkien"):
		value["Price"] = 90
		ref.child(key).update({"Price":80})
        
        </code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-209.png" class="kg-image" alt="image-209" width="600" height="400" loading="lazy"><figcaption>Esquema de la base de datos luego de usar la función update()</figcaption></figure><h2 id="como-recuperar-informaci-n-desde-la-base-de-datos-firebase-usando-python"><strong>Como recuperar información desde la base de datos Firebase usando Python</strong></h2><p>Ya hemos recuperado información usando el método <code>get()</code> cuando estábamos tratando de actualizar una clave en particular. Ahora, veremos unos cuantos métodos más y los agruparemos para realizar complejas solicitudes.</p><p>Vamos a obtener todos los libros en orden, ordenados según el precio usando el método <code>order_by_child()</code>. Para aplicar este método, en primer lugar debemos configurar la clave para la cual estamos realizando la solicitud como el campo índice mediante la regla <code>.indexOn</code> en las reglas de seguridad de Firebase.</p><p>Si queremos ordenar según precio, entonces el precio debe estar registrado como índice. Puedes colocar el valor así:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-210.png" class="kg-image" alt="image-210" width="600" height="400" loading="lazy"><figcaption>Ve a la pestaña reglas y escribe en la estructura del esquema donde quieras colocar el índice</figcaption></figure><pre><code>ref = db.reference("/Books/Best_Sellers/")
print(ref.order_by_child("Price").get())</code></pre><p>El valor retornado de este método es un OrderedDict. Para ordenar según clave, use <code>order_by_key()</code>. Para obtener el libro con el precio máximo, usamos el método <code>limit_to_last()</code> de la siguiente manera:</p><pre><code>ref.order_by_child("Price").limit_to_last(1).get()</code></pre><p>Por otro lado, para obtener el libro con el precio más bajo, escribimos lo siguiente:</p><pre><code>ref.order_by_child("Price").limit_to_first(1).get()</code></pre><p>Para obtener los libros que estén exactamente con el precio de 80 unidades, usamos lo siguiente:</p><pre><code>ref.order_by_child("Price").equal_to(80).get()</code></pre><p>Para más ejemplos y métodos para consultar su base de datos según sus necesidades, revise la documentación oficial <a href="https://firebase.google.com/docs/database/admin/retrieve-data">aquí</a>.</p><h2 id="como-eliminar-informaci-n-de-firebase-usando-python"><strong>Como eliminar información de Firebase usando Python</strong></h2><p>Eliminar información es bastante simple. Vamos a eliminar todos los libros más vendidos con J.R.R. Tolkien como autor.</p><pre><code>ref = db.reference("/Books/Best_Sellers")

for key, value in best_sellers.items():
	if(value["Author"] == "J.R.R. Tolkien"):
		ref.child(key).set({})
        
        </code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-211.png" class="kg-image" alt="image-211" width="600" height="400" loading="lazy"><figcaption>Esquema de la base de datos luego de eliminar información</figcaption></figure><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>En este post, hemos aprendido como crear una base de datos en tiempo real Firebase, llenarla con información, y borrarla, actualizar y consultar la información usando Python.</p><p>Espero esto ayude a algún desarrollador Python ahí fuera, quien está recientemente descubriendo la belleza de Firebase, pero se siente abrumado con tantas opciones y métodos para elegir. Si has leído hasta acá, ¡muchísimas gracias! Cuídese y ¡feliz codeo!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Que significa el // en Python? Operadores en Python ]]>
                </title>
                <description>
                    <![CDATA[ En Python, se usa el operador barra doble // para realizar una división. Este operador // divide al primer número por el segundo número y redondea hacia abajo el resultado al entero más cercano. En este artículo, voy a mostrarte como se usa el operador // y lo compararemos con ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/que-significa-doble-barra-en-python/</link>
                <guid isPermaLink="false">63014cce7b4ec209a4024e90</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jose González ]]>
                </dc:creator>
                <pubDate>Thu, 22 Sep 2022 17:50:55 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/09/doubleSlash.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-does-double-slash-mean-in-python/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">What Does // Mean in Python? Operators in Python</a>
      </p><p>En Python, se usa el operador barra doble <code>//</code> para realizar una división. Este operador <code>//</code> divide al primer número por el segundo número y redondea hacia abajo el resultado al entero más cercano.</p><p>En este artículo, voy a mostrarte como se usa el operador <code>//</code> y lo compararemos con la división regular para que puedas observar como funciona.</p><p>No termina solo ahí, además – aprenderás de un comando matemático en Python que es sinónimo con el operador barra doble <code>//</code>.</p><h2 id="lo-que-veremos"><strong>Lo que veremos</strong></h2><ul><li>La sintaxis básica del operador<code>//</code></li><li>Ejemplos de la división "entera"</li><li>El operador doble barra <code>//</code> funciona como <code>math.floor()</code></li><li>Como funciona el operador doble barra <code>//</code> tras bambalinas</li><li>Conclusión</li></ul><h2 id="la-sintaxis-b-sica-del-operador-doble-barra-"><strong>La sintaxis básica del operador doble barra </strong><code><strong>//</strong></code><strong> </strong></h2><p>Para usar el operador doble barra <code>//</code>, se hace de la misma manera que como lo harías con una división regular. La única diferencia es que en lugar de solo ocupar una barra <code>/</code>, usas el doble de barras <code>//</code>:</p><pre><code class="language-py">Primer Número // Segundo Número
</code></pre><h2 id="ejemplos-de-divisi-n-entera"><strong>Ejemplos de división "entera"</strong></h2><p>En el ejemplo de a continuación, la división "entera" de 12 en 5 da como resultado 2:</p><pre><code class="language-py">num1 = 12
num2 = 5
num3 = num1 // num2

print("División entera de", num1, "en", num2, "=", num3)
# Salida: División entera de 12 en 5 = 2
</code></pre><p>En cambio, la división regular de 12 en 5 dará como resultado 2.4. Eso es 2 enteros 4 décimos:</p><pre><code class="language-py">num2 = 5
num3 = num1 / num2

print("División regular de", num1, "en", num2, "=", num3)
# Salida: División regular de 12 en 5 = 2.4
</code></pre><p>Esto muestra que el operador <code>//</code> aproxima hacia abajo el resultado de una división entre dos números al número entero (o completo) más cercano.</p><p>Incluso en el caso de que el número decimal sea 9, el operador <code>//</code> aun así va a continuar aproximando hacia el resultado entero más cercano, pero hacia abajo.</p><pre><code class="language-py">num1 = 29 
num2 = 10 
num3 = num1 / num2
num4 = num1 // num2

print("División regular de", num1, "en", num2, "=", num3)
print("División entera de", num1, "en", num2, "=", num4)

"""
Salida:
División regular de 29 en 10 = 2.9
División entera de 29 en 10 = 2
"""
</code></pre><p>Y si realizas una división entera con un número negativo, el resultado aún seguirá redondeándose al número entero más pequeño y más cercano.</p><p>Para preparar tu mente para el resultado, redondear hacia abajo un número negativo significa alejarse del 0. Por lo tanto, -12 dividido en 5 dará como resultado -3. No te confundas, aunque a primeras luces uno podría decir que el resultado en realidad se está haciendo más grande, la verdad es que se está haciendo más pequeño, ya que mientras más lejano está el número negativo del 0, más pequeña es la cantidad que representa.</p><pre><code class="language-py">num1 = -12
num2 = 5
num3 = num1 // num2

print("División entera de", num1, "en", num2, "=", num3)

# División entera de -12 en 5 = -3
</code></pre><h2 id="el-operador-doble-barra-funciona-igual-que-math-floor-"><strong>El operador doble barra <code>//</code> funciona igual que <code>math.floor()</code></strong></h2><p>En Python, <code>math.floor()</code> redondea hacia abajo un número hacia su entero más cercano, justo como lo hace el operador doble barra <code>//</code>.</p><p>Así que, <code>math.floor()</code> es una alternativa al operador <code>//</code> porque tras bambalinas realizan lo mismo.</p><p>Acá tienes un ejemplo:</p><pre><code class="language-py">import math

num1 = 12
num2 = 5
num3 = num1 // num2
num4 = math.floor(num1 / num2)

print("División entera de", num1, "en", num2, "=", num3)
print("math.floor de", num1, "dividido en", num2, "=", num4)

"""
Salida:
División entera de 12 en 5 = 2
math.floor de 12 dividido en 5 = 2
"""
</code></pre><p>Puedes ver que <code>math.floor()</code> realiza lo mismo que el operador <code>//</code>.</p><h2 id="como-el-operador-doble-barra-funciona-tras-bambalinas"><strong>Como el operador doble barra <code>//</code> funciona tras bambalinas</strong></h2><p>Cuando usas el operador <code>//</code> para dividir dos números, el comando que es llamado tras bambalinas es <code>__floordiv__()</code>.</p><p>También puedes usar este comando <code>__floordiv__()</code> directamente en lugar de colocar el operador <code>//</code>:</p><pre><code class="language-py">num1 = 12
num2 = 5
num3 = num1 // num2
num4 = num1.__floordiv__(num2)

print("División entera de", num1, "en", num2, "=", num3)
print("usando el comando floordiv se obtiene el mismo valor de", num4)

"""
Salida:
División entera de 12 en 5 = 2
usando el comando floordiv se obtiene el mismo valor de 2
"""
</code></pre><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>En este artículo, has aprendido como se usa el operador doble barra <code>//</code> &nbsp;y como opera tras bambalinas.</p><p>Además, has aprendido dos alternativas al operador <code>//</code>, estas son: <code>math.floor()</code> y <code>__floordiv__()</code>.</p><p>No te confundas sobre cuál usar. Las tres maneras distintas producirán exactamente el mismo resultado. Te aconsejaría el uso del operador doble barra <code>//</code> ya que netamente escribes menos caracteres para su uso.</p><p>Gracias por la lectura.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como llamar una función en Python: Ejemplo de la sintaxis en Def ]]>
                </title>
                <description>
                    <![CDATA[ En Python, como en otros lenguajes de programación, puedes usar las funciones para evitar repetirte y reutilizar piezas de código. Para que las funciones puedan trabajar, no solo las escribes y ya – debes llamarlas o invocarlas también. Antes de que llames una función, necesitas escribirlas con la palabra clave ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-llamar-a-una-funcion-en-python-ejemplo-de-sintaxis-def/</link>
                <guid isPermaLink="false">63013f687b4ec209a4024d6e</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jose González ]]>
                </dc:creator>
                <pubDate>Thu, 22 Sep 2022 17:28:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/09/callFunction.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-call-a-function-in-python-def-syntax-example/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Call a Function in Python – Def Syntax Example</a>
      </p><p>En Python, como en otros lenguajes de programación, puedes usar las funciones para evitar repetirte y reutilizar piezas de código.</p><p>Para que las funciones puedan trabajar, no solo las escribes y ya – debes llamarlas o invocarlas también.</p><p>Antes de que llames una función, necesitas escribirlas con la palabra clave <em>Def.</em> Así que, en este artículo, no solo te mostraré como llamar una función, sino que también, te mostraré como crearla.</p><h2 id="lo-que-veremos"><strong>Lo que veremos</strong></h2><ul><li>Como definir una función con la palabra clave <code>def</code></li><li>Como llamar una función en Python</li><li>Como llamar una función anidada en Python</li><li>Conclusiones </li></ul><h2 id="como-definir-una-funci-n-con-la-palabra-clave-def"><strong>Como definir una función con la palabra clave <code>def</code></strong></h2><p>Para definir una función en Python, debes escribir en primer lugar la palabra clave <em>def</em>, seguido del nombre de la función y los paréntesis.</p><p>Para decirle a Python que la función es un bloque de código, colocas un <em>dos puntos </em>(:)<em> </em>tras del nombre de la función. Lo que sigue, es lo que quieres que haga la función.</p><p>La sintaxis básica de una función se ve de la siguiente manera:</p><pre><code class="language-py">def nombre_función():
    # Lo que quieres que haga tu función
</code></pre><p>Un ejemplo de una función puede ser el siguiente:</p><pre><code class="language-py">def aprender_a_programar():
    print("Puedes aprender a programar gratis en freeCodeCamp")

</code></pre><p>Lo que queremos que esta función haga es mostrar el texto &nbsp;<code>puedes aprender a programar gratis en freeCodeCamp</code> en la terminal.</p><p>Para que esta función se ejecute, debemos llamarla. Eso es lo que haremos a continuación.</p><h2 id="como-llamar-una-funci-n-en-python"><strong>Como llamar una función en Python</strong></h2><p>Para llamar una función, debes escribir el nombre de la función seguido de dos paréntesis cerrados.</p><p>La sintaxis al llamar una función debe verse de la siguiente manera:</p><pre><code class="language-py">nombre_función()
</code></pre><p>Para llamar la función definida previamente, debemos escribir <code>aprender_a_programar()</code>:</p><pre><code class="language-py">def aprender_a_programar():
    print("Puedes aprender a programar gratis en freeCodeCamp")

aprender_a_programar()
# Salida: Puedes aprender a programar gratis en freeCodeCamp
</code></pre><p><strong><strong>N</strong>ota</strong>: Asegúrate de jamás especificar la llamada de la función <em>dentro</em> del bloque donde se configura que ha de hacer tu función. No va a funcionar porque pasará a ser tratada como parte de la función que se está ejecutando.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/07/ss1-3.png" class="kg-image" alt="ss1-3" width="600" height="400" loading="lazy"></figure><p>Puedes ver que la función no mostró nada, ya que he intentado llamarle desde dentro del bloque de la función.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/07/ss2-4.png" class="kg-image" alt="ss2-4" width="600" height="400" loading="lazy"></figure><p>En este caso, la función se ejecuta correctamente, porque le he llamado desde afuera del bloque de la función.</p><h2 id="como-llamar-una-funci-n-anidada-en-python"><strong>Como llamar una función anidada en Python</strong></h2><p>Puede ser un poco confuso el llamar una función anidada, así que quiero mostrarte como hacerlo.</p><p>A continuación está la función anidada:</p><pre><code class="language-py">def aprender_a_programar():
    print("Puedes aprender a programar gratis en freeCodeCamp")

    def aprender_que_lenguaje():
        print("Puedes aprender cualquier lenguaje de programación en el canal de YouTube de freeCodeCamp")
  
</code></pre><p>La función <code>aprender_que_lenguaje</code> es parte de la función<code>aprender_a_programar</code> porque está anidada o definida dentro de ella.</p><p>Si escribes <code>aprender_a_programar()</code> y ejecutas el código, solo la función externa (aprender_a_programar) es llamada:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/07/ss3-3.png" class="kg-image" alt="ss3-3" width="600" height="400" loading="lazy"></figure><p><br>Puedes observar en la imagen anterior que solo la función exterior fue llamada y que la función interna está atenuada.</p><p>Para llamar una función interior, deberías escribir <code>aprender_que_lenguaje()</code> de forma precisa. Pero, ¿por qué?</p><p>Deberías observar justo debajo del bloque interior de la función definida por la palabra clave <em>def</em> y escribir el llamado de la función ahí.</p><p>Pero, si solo haces eso, tampoco funcionará, ya que debes llamar a la función externa también.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/07/ss4-3.png" class="kg-image" alt="ss4-3" width="600" height="400" loading="lazy"></figure><p><br>Puedes ver que la función interior (<code>aprender_que_lenguaje</code>) aún no hace lo que queremos que haga.</p><p>Para que funcione correctamente, debes llamar ambas funciones donde sea necesario:</p><pre><code class="language-py">def aprender_a_programar():
    print("Puedes aprender a programar gratis en freeCodeCamp")

    def aprender_que_lenguaje():
        print("Puedes aprender cualquier lenguaje de programación en el canal de YouTube de freeCodeCamp")
    
    aprender_que_lenguaje()

aprender_a_programar()

"""
Salida:
Puedes aprender a programar gratis en freeCodeCamp
Puedes aprender cualquier lenguaje de programación en el canal de YouTube de freeCodeCamp
"""
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/07/ss5-4.png" class="kg-image" alt="ss5-4" width="600" height="400" loading="lazy"></figure><p>Puedes ver que todo salió como se esperaba.</p><h2 id="conclusiones"><strong>Conclusiones</strong></h2><p>Espero que este artículo haya sido de ayuda en tu aprendizaje en como correctamente llamar una función utilizando Python.</p><p>Si quieres aprender más sobre Python, puedes revisar <a href="https://www.freecodecamp.org/learn/scientific-computing-with-python/">freeCodeCamp Python curriculum</a>. Es completamente gratis.</p><p>Sigue Programando :)</p><p></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Proyecto en Python: Cómo construir el J.A.R.V.I.S de Tony Stark usando Python ]]>
                </title>
                <description>
                    <![CDATA[ ¿Recuerdas a J.A.R.V.I.S., el asistente personal virtual de Tony Stark?. Si has visto alguna de las películas de Ironman o Los Vengadores, entonces estoy seguro de que lo recuerdas. ¿Alguna vez te preguntaste si podrías crear tu propio asistente personal?, ¿sí?, pues, ¡Tony Stark puede ayudarnos con eso!. Oops, ¿acaso ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/proyecto-python-como-construir-el-jarvis-de-tony-stark-con-python/</link>
                <guid isPermaLink="false">62fade387b4ec209a4023bd8</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jose González ]]>
                </dc:creator>
                <pubDate>Thu, 22 Sep 2022 17:17:29 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/09/png_20211209_232339_0000.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/python-project-how-to-build-your-own-jarvis-using-python/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python Project – How to Build Tony Stark's JARVIS with Python</a>
      </p><p>¿Recuerdas a J.A.R.V.I.S., el asistente personal virtual de Tony Stark?. Si has visto alguna de las películas de Ironman o Los Vengadores, entonces estoy seguro de que lo recuerdas.</p><p>¿Alguna vez te preguntaste si podrías crear tu propio asistente personal?, ¿sí?, pues, ¡Tony Stark puede ayudarnos con eso!.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/12/tony-snap2_rv5gmh.jpg" class="kg-image" alt="tony-snap2_rv5gmh" width="600" height="400" loading="lazy"></figure><p>Oops, ¿acaso olvidaste que ya no está?. Es triste que ya no sea capaz de salvarnos. Pero, tu lenguaje de programación favorito, Python, puede ayudarte.</p><p>Si, leíste bien. Podemos crear nuestro propio J.A.R.V.I.S., usando Python. ¡Vamos a ello!</p><h2 id="preparaci-n-del-proyecto"><strong>Preparación del Proyecto</strong></h2><p>Mientras estés escribiendo el código de este proyecto, te vas a encontrar con varios módulos y librerías externas. Aprendamos acerca de ellas e instalémoslas. Pero antes de instalarlas, creemos un entorno virtual y activémoslo.</p><p>Vamos a crear un entorno virtual usando <code>virtualenv</code>. Python ahora viene con una librería <code>virtualenv</code> preinstalada. Así que, para crear nuestro entorno virtual puedes usar el comando de abajo:</p><pre><code class="language-bash">$ python -m venv env</code></pre><p>El comando anterior va a crear un entorno virtual llamado <code>env</code>. Ahora, necesitamos activar el entorno usando el siguiente comando:</p><pre><code class="language-bash">$ . env/Scripts/activate</code></pre><p>Para verificar si es que el entorno ha sido activado o no, puedes ver <code>(env)</code>en tu terminal. Ahora, podemos instalar las librerías.</p><h3 id="1-pyttsx3-">1. pyttsx3: </h3><p>pyttsx es una librería multi-plataforma de texto a voz que es independiente a la plataforma donde se ejecute. La mayor ventaja de usar esta librería de conversión texto-a-voz es que trabaja sin conexión. Para instalar este modulo, escriba el siguiente comando en la terminal:</p><pre><code class="language-bash">$ pip install pyttsx3</code></pre><h3 id="2-speechrecognition-">2. SpeechRecognition:</h3><p>Esto nos permite convertir audio em texto para su procesamiento. Para instalar este module, escribe el siguiente comando en la terminal:</p><pre><code class="language-bash">$ pip install SpeechRecognition</code></pre><h3 id="3-pywhatkit-">3. pywhatkit:</h3><p>Esta es una librería de fácil uso que nos ayudará a interactuar con el navegador de forma más sencilla. Para instalar este módulo, ejecuta el siguiente comando en la terminal:</p><pre><code class="language-bash">$ pip install pywhatkit</code></pre><h3 id="4-wikipedia-">4. wikipedia:</h3><p>Vamos a usarla para buscar una gran variedad de información del sitio web de Wikipedia. Para instalar este módulo, escribe el comando de a continuación en la terminal:</p><pre><code class="language-bash">$ pip install wikipedia</code></pre><h3 id="5-requests-">5. requests:</h3><p>Esta es una simple y elegante librería HTTP para Python que te permite enviar peticiones en HTTP/1.1 de manera muy sencilla. Para instalar este módulo, ejecuta el siguiente comando en la terminal:</p><pre><code class="language-bash">$ pip install requests</code></pre><h3 id="archivo-env">Archivo .env</h3><p>Necesitamos este archivo para poder alojar datos privados como claves API, contraseñas, así como todo lo que relacionado con el proyecto. Por ahora, vamos a almacenar el nombre del usuario y del bot.</p><p>Crea un archivo con el nombre <code>.env</code> y agrega la siguiente información allí:</p><pre><code>USER=Usuario
BOTNAME=JARVIS</code></pre><p>Para usar esta información del archivo <code>.env</code>, debemos instalar otro módulo llamado <strong>python-decouple</strong> así:</p><pre><code class="language-bash">$ pip install python-decouple</code></pre><p>Aprenda más acerca de los Entornos Variables en Python <a href="https://iread.ga/posts/49/do-you-really-need-environment-variables-in-python">aquí</a>.</p><h2 id="como-configurar-jarvis-con-python"><strong>Como configurar JARVIS con Python</strong></h2><p>Antes de que comencemos a definir algunas importantes funciones. Creemos primero un motor de voz.</p><pre><code class="language-python">import pyttsx3
from decouple import config

USERNAME = config('USER')
BOTNAME = config('BOTNAME')


engine = pyttsx3.init('sapi5')

# Set Rate
engine.setProperty('rate', 190)

# Set Volume
engine.setProperty('volume', 1.0)

# Set Voice (Female)
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[1].id)</code></pre><p>Analicemos el código anterior. Primero que todo, hemos inicializado un <code>engine</code> usando el módulo <code>pyttsx3</code>. <code>sapi5</code> es una API de voz de Microsoft que nos ayuda a usar las voces. Aprende más acerca de eso <a href="https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee125663(v=vs.85)">aquí</a>.</p><p>A continuación, vamos a configurar las propiedades de <code>rate</code> y <code>volume</code> del motor de voz usando <code>setProperty</code>.</p><p>Luego, podemos obtener las voces del motor usando <code>getProperty</code>. <code>voices</code> será una lista de voces disponibles en nuestro sistema. Si le visualizamos, podremos ver algo como lo siguiente:</p><pre><code class="language-bash">[&lt;pyttsx3.voice.Voice object at 0x000001AB9FB834F0&gt;, &lt;pyttsx3.voice.Voice object at 0x000001AB9FB83490&gt;]</code></pre><p>La primera corresponde a una voz masculina y la siguiente es una voz femenina. JARVIS solía ser un asistente masculino en las películas, pero he elegido fijar la propiedad <code>voice</code> a la femenina para este tutorial utilizando <code>setProperty</code>.</p><p>Nota: Si aparece un error relacionado a Pyaudio, descarga el archivo wheel Pyaudio.whl desde <a href="https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyaudio">aquí</a> e instálelo dentro del entorno virtual. </p><p>Además, usando <code>config</code> desde <em><em>decouple</em></em>, estamos obteniendo el valor de <code>USER</code> y <code>BOTNAME</code> de las variables del entorno.</p><h3 id="habilitar-la-funci-n-hablar"><strong>Habilitar la función Hablar</strong></h3><p>La función Hablar será la responsable de enunciar cualquier texto que pase por ella. Veamos el código:</p><pre><code class="language-python"># Conversión Texto a Voz
def speak(text):
    """Usado para decir cualquier texto que le sea entregado"""
    
    engine.say(text)
    engine.runAndWait()
</code></pre><p>En <code>speak()</code>, el motor dice oralmente cualquier texto que es entregado mediante el uso de <code>say()</code>. El uso de <code>runAndWait()</code>, &nbsp;se bloquea durante el bucle de eventos y vuelve cuando se borra la cola de comandos.</p><h3 id="habilitar-la-funci-n-dar-la-bienvenida"><strong>Habilitar la función Dar la bienvenida</strong></h3><p>Esta función será usada para dar la bienvenida al usuario cada momento que el programa se ejecuta. En concordancia con el horario en tiempo real, saludará con Buenos Días, Buenas Tardes, o Buenas Noches al usuario.</p><pre><code class="language-python">from datetime import datetime


def greet_user():
    """Saluda al usuario de acuerdo al horario"""
    
    hour = datetime.now().hour
    if (hour &gt;= 6) and (hour &lt; 12):
        speak(f"Buenos días {USERNAME}")
    elif (hour &gt;= 12) and (hour &lt; 16):
        speak(f"Buenas tardes {USERNAME}")
    elif (hour &gt;= 16) and (hour &lt; 19):
        speak(f"Buenas noches {USERNAME}")
    speak(f"Yo soy {BOTNAME}. ¿Cómo puedo asistirle?")
</code></pre><p>En primer lugar, consideramos la hora actual, en la situación que la hora actual sea las 11:15 AM, la hora será las 11. Si el valor de la hora está entre 6 AM y 12 PM, deseará los <em>Buenos Días</em> al usuario. Si el valor está entre 12 PM y 4 PM, le deseará las <em>Buenas Tardes</em> al usuario y de la misma manera, si el valor está entre las 4 PM y las 7 PM, le deseará las <em>Buenas Noches</em>. Estamos ocupando <code>speak()</code> para hablarle al usuario.</p><h3 id="como-obtener-informarci-n-del-usuario"><strong>Como obtener informarción del usuario</strong></h3><p>Usamos esta función para poder tomar instrucciones o comandos por parte del usuario y también, poder reconocer el comando usando el módulo <code>speech_recognition</code>.</p><pre><code class="language-python">import speech_recognition as sr
from random import choice
from utils import opening_text


def take_user_input():
    """Toma las entradas del usuario, las reconoce utilizando el módulo de reconocimiento de voz y lo transforma a texto"""

    r = sr.Recognizer()
    with sr.Microphone() as source:
        print('Escuchando....')
        r.pause_threshold = 1
        audio = r.listen(source)

    try:
        print('Reconociendo...')
        query = r.recognize_google(audio, language='es-es')
        if not 'Salir' in query or 'Alto' in query:
            speak(choice(opening_text))
        else:
            hour = datetime.now().hour
            if hour &gt;= 21 and hour &lt; 6:
                speak("Buenas noches señor, !cuídese!")
            else:
                speak('¡Tenga un buen día señor!')
            exit()
    except Exception:
        speak('Disculpe, no he podido entender. ¿Podría decirlo de nuevo?')
        query = 'None'
    return query</code></pre><p>Hemos importado el módulo <code>speech_recognition</code> como <code>sr</code>. La clase <em><em>Recognizer</em></em> dentro del módulo <code>speech_recognition</code> nos ayuda a reconocer el audio. El mismo módulo también tiene una clase <em><em>Microphone</em></em> que nos da acceso al micrófono del dispositivo. Así, con el micrófono como <code>source</code>, escuchamos el audio mediante el uso de <code>listen()</code> en la clase <em><em>Recognizer</em></em>.</p><p>Además, hemos fijado el valor de <code>pause_threshold</code> a 1, para que no compile, aunque hagamos una pausa de 1 segundo mientras hablamos.</p><p>Luego, usando <code>recognize_google()</code> desde la clase <em><em>Recognizer</em></em>, tratamso de reconocer el audio. El <code>recognize_google()</code> ejecuta un reconocimiento de voz en el audio que entregado, usando la <strong>API de reconocimiento de voz de Google</strong>.</p><p>Hemos fijado el lenguaje a <code>es-es</code>, el cual es el español que se habla en la España. Va a dar como resultado la transcripción del audio que no es más que una cadena. La almacenamos en una variable llamada <code>query</code>.</p><p>Si la variable query tiene las palabras <strong>salir<strong> </strong></strong>o <strong>al<strong>to </strong></strong>en ella, significa que le estamos pidiendo al asistente que se detenga inmediatamente. Así que, antes de detenerse, saludamos al usuario según la hora correspondiente. Si la hora está entre 21 y 6, le deseamos las <em>Buenas Noches</em> al usuario, además de algún otro mensaje.</p><p>Creamos el archivo <code>utils.py</code> el cual es solo una lista con algunas oraciones como:</p><pre><code class="language-python">opening_text = [
    "Genial, estoy en ello señor.",
    "Okay señor, trabajaré en ello.",
    "Deme un segundo señor.",
]</code></pre><p>Si la variable query no tiene ninguna de estas dos palabras (exit or stop), entonces se dice algo para que sepa que le hemos escuchado. Para lograr eso, usaremos el comando choice() del módulo random para aleatoriamente seleccionar alguna de las oraciones que están en la lista de <code>opening_text</code>. Luego de hablar, salimos del programa.</p><p>Durante todo el proceso, si encontramos una excepción, nos disculpamos con ekl usuario y fijamos el valor de <code>query</code> a None. Al final, retornamos el valor de <code>query</code>.</p><h2 id="como-configurar-las-funciones-sin-conexi-n"><strong>Como configurar las funciones sin conexión</strong></h2><p>Dentro de la carpeta <code>functions</code>, crear una archivo Python llamado <code>os_ops.py</code>. En este archivo, crearemos varias funciones para interactuar con el sistema operativo.</p><pre><code class="language-python">import os
import subprocess as sp

paths = {
    'notepad': "C:\\Program Files\\Notepad++\\notepad++.exe",
    'discord': "C:\\Users\\ashut\\AppData\\Local\\Discord\\app-1.0.9003\\Discord.exe",
    'calculator': "C:\\Windows\\System32\\calc.exe"
}
</code></pre><p>En código anterior, hemos creado un diccionario llamado <code>paths</code> el cual tiene el nombre de un software como clave y su dirección como valor. Puedes modificar las direcciones de acuerdo a tu propio sistema y agregar más si lo estimas necesario.</p><h3 id="como-abrir-la-camara"><strong>Como abrir la camara</strong></h3><p>Vamos a usar la siguiente función para abrir la cámara de nuestro sistema. Usaremos el módulo <code>subprocess</code> para ejecutar esta instrucción.</p><pre><code class="language-python">def open_camera():
    sp.run('start microsoft.windows.camera:', shell=True)</code></pre><h3 id="como-abrir-notepadd-y-discord"><strong>Como abrir Notepadd++ y Discord</strong></h3><p>Usaremos las siguientes funciones para abrir Notepad++ y Discord en el sistema.</p><pre><code class="language-python">def open_notepad():
    os.startfile(paths['notepad'])


def open_discord():
    os.startfile(paths['discord'])</code></pre><h3 id="como-abrir-la-consola-de-comandos"><strong>Como abrir la consola de comandos</strong></h3><p>Usaremos la siguiente función para abrir la consola de comandos de nuestro sistema.</p><pre><code class="language-python">def open_cmd():
    os.system('start cmd')</code></pre><h3 id="como-abrir-la-calculadora"><strong>Como abrir la calculadora</strong></h3><p>Usaremos la función de a continuación para abrir la calculadora de nuestro sistema.</p><pre><code class="language-python">def open_calculator():
    sp.Popen(paths['calculator'])</code></pre><h2 id="como-configurar-las-funciones-con-conexi-n"><strong>Como configurar las funciones con conexión</strong></h2><p>Agregaremos varias funciones en línea. Estas son:</p><ol><li>Encuentra mi dirección IP</li><li>Busca en Wikipedia</li><li>Reproduce videos en YouTube</li><li>Busca en Google</li><li>Envía un mensaje por Whatsapp</li><li>Envía un Correo electrónico</li><li>Obtén los últimos titulares de las noticias</li><li>Obtén el reporte del clima</li><li>Obtén las películas en tendencia</li><li>Obtener chistes aleatoriamente</li><li>Obtener algún consejo al azar</li></ol><p>Creemos un archivo llamado <code>online_ops.py</code> dentro del directorio <code>functions</code>, y comencemos a crear estas funciones una tras la otra. Por ahora, agrega el siguiente código en el archivo:</p><pre><code class="language-python">import requests
import wikipedia
import pywhatkit as kit
from email.message import EmailMessage
import smtplib
from decouple import config</code></pre><p>Antes de empezar a trabajar con las API, si no has trabajado con las API y no sabes como manipularlas utilizando Python, revisa <a href="https://iread.ga/posts/26/python-api-tutorial">este tutorial</a>.</p><h3 id="como-agregar-la-funci-n-encuentra-mi-direcci-n-ip"><strong>Como agregar la función Encuentra mi dirección IP</strong></h3><p><a href="https://www.ipify.org/">ipify</a> entrega una API bastante sencilla para las direcciones públicas IP. Solo necesitamos realizar una solicitud GET en la siguiente URL: <a href="https://api64.ipify.org/?format=json">https://api64.ipify.org/?format=json</a>. Devolverá la JSON data como:</p><pre><code class="language-json">{
  "ip": "117.214.111.199"
}</code></pre><p>Entonces, podríamos simplemente mostrar la <code>ip</code> desde la JSON data. Así que, creemos dicho comando:</p><pre><code class="language-python">def find_my_ip():
    ip_address = requests.get('https://api64.ipify.org?format=json').json()
    return ip_address["ip"]</code></pre><h3 id="como-agregar-la-funci-n-de-b-squeda-en-wikipedia"><strong>Como agregar la función de Búsqueda en Wikipedia</strong></h3><p>Para buscar en Wikipedia, usaremos el módulo <code>wikipedia</code> que hemos instalado previamente en este tutorial.</p><pre><code class="language-python">def search_on_wikipedia(query):
    results = wikipedia.summary(query, sentences=2)
    return results</code></pre><p>Dentro del módulo <code>wikipedia</code>, tenemos un <code>summary()</code> que acepta una variable query como elemento. Adicionalmente, podemos indicar el número de oraciones requeridas. Y, entonces, simplemente mostrar el resultado.</p><h3 id="como-agregar-la-funci-n-para-reproducir-videos-en-youtube"><strong>Como agregar la función para Reproducir videos en YouTube</strong></h3><p>Para reproducir videos en YouTube, usaremos <em><em>PyWhatKit</em></em>. El cual ya hemos importado mediante <code>kit</code>.</p><pre><code class="language-python">def play_on_youtube(video):
    kit.playonyt(video)</code></pre><p><em><em>PyWhatKit</em></em> tiene un <code>playonyt()</code> que acepta un tema como elemento. Entonces busca dicho tema en YouTube y reproduce el video más apropiado. Usa <a href="https://pyautogui.readthedocs.io/en/latest/">PyAutoGUI </a>de manera encubierta.</p><h3 id="como-agregar-la-funci-n-de-b-squeda-en-google"><strong>Como agregar la función de búsqueda en google</strong></h3><p>Nuevamente, usaremos <em><em>PyWhatKit</em></em> para la búsqueda en google.</p><pre><code class="language-python">def search_on_google(query):
    kit.search(query)</code></pre><p>Tiene un comando <code>search()</code> que nos ayuda a buscar en Google instantáneamente.</p><h3 id="como-agregar-la-funci-n-enviar-un-mensaje-v-a-whatsapp"><strong>Como agregar la función Enviar un mensaje vía WhatsApp</strong></h3><p>Estaremos usando <em><em>PyWhatKit</em></em> nuevamente para enviar mensajes por whatsapp.</p><pre><code class="language-python">def send_whatsapp_message(number, message):
    kit.sendwhatmsg_instantly(f"+91{number}", message)</code></pre><p>Nuestro comando acepta dos elementos &nbsp;– el número de teléfono <code>number</code> y el <code>message</code>. Entonces llama a <code>sendwhatmsg_instantly()</code> para enviar un mensaje WhatsApp. Asegúrate de estar con la sesión de WhatsApp iniciada en WhatsApp Web.</p><h3 id="como-agregar-la-funci-n-de-enviar-email"><strong>Como agregar la función de enviar email</strong></h3><p>Para enviar emails, estaremos usando el módulo preinstalado <code>smtplib</code> de Python.</p><pre><code class="language-python">EMAIL = config("EMAIL")
PASSWORD = config("PASSWORD")


def send_email(receiver_address, subject, message):
    try:
        email = EmailMessage()
        email['To'] = receiver_address
        email["Subject"] = subject
        email['From'] = EMAIL
        email.set_content(message)
        s = smtplib.SMTP("smtp.gmail.com", 587)
        s.starttls()
        s.login(EMAIL, PASSWORD)
        s.send_message(email)
        s.close()
        return True
    except Exception as e:
        print(e)
        return False</code></pre><p>El comando acepta <code>receiver_address</code>, <code>subject</code>, y <code>message</code> como elementos. Creamos un objeto de clase <em><em>SMTP </em></em>del módulo <code>smtplib</code>. Toma un <strong><strong>hos</strong>t </strong>y un <strong><strong>port number</strong></strong> como parámetros.</p><p>Entonces iniciamos la sesión e ingresamos con la dirección de correo electrónico y la contraseña, para enviar el correo electrónico. Asegúrate de agregar tu <strong>Correo electrónico</strong> y tu <strong>contraseña</strong> en el archivo <code>.env</code>.</p><h3 id="como-agregar-la-funci-n-para-obtener-los-ltimos-titulares-de-las-noticias"><strong>Como agregar la función para obtener los últimos titulares de las noticias</strong></h3><p>Para buscar los titulares de las últimas noticias, usaremos la <a href="https://newsapi.org/">NewsAPI</a>. Nos registramos con una cuenta gratuita en NewsAPI y obtenemos nuestra clave API. Agregamos nuestra <strong><strong>NEWS_API_KEY </strong></strong>el archivo <code>.env</code>.</p><pre><code class="language-python">NEWS_API_KEY = config("NEWS_API_KEY")


def get_latest_news():
    news_headlines = []
    res = requests.get(
        f"https://newsapi.org/v2/top-headlines?country=in&amp;apiKey={NEWS_API_KEY}&amp;category=general").json()
    articles = res["articles"]
    for article in articles:
        news_headlines.append(article["title"])
    return news_headlines[:5]</code></pre><p>En el comando anterior, primero estamos creando una lista vacía llamada <code>news_headlines</code>. Entonces haremos una solicitud GET en la API URL especificada en la <a href="https://newsapi.org/docs">Documentacion NewsAPI</a>. Una muestra de una respuesta JSON de la solicitud luce como lo siguiente:</p><pre><code class="language-json">{
  "status": "ok",
  "totalResults": 38,
  "articles": [
    {
      "source": {
        "id": null,
        "name": "Sportskeeda"
      },
      "author": "Aniket Thakkar",
      "title": "Latest Free Fire redeem code to get Weapon loot crate today (14 October 2021) - Sportskeeda",
      "description": "Gun crates are one of the ways that players in Free Fire can obtain impressive and appealing gun skins.",
      "url": "https://www.sportskeeda.com/free-fire/latest-free-fire-redeem-code-get-weapon-loot-crate-today-14-october-2021",
      "urlToImage": "https://staticg.sportskeeda.com/editor/2021/10/d0b83-16341799119781-1920.jpg",
      "publishedAt": "2021-10-14T03:51:50Z",
      "content": null
    },
    {
      "source": {
        "id": null,
        "name": "NDTV News"
      },
      "author": null,
      "title": "BSF Gets Increased Powers In 3 Border States: What It Means - NDTV",
      "description": "Border Security Force (BSF) officers will now have the power toarrest, search, and of seizure to the extent of 50 km inside three newstates sharing international boundaries with Pakistan and Bangladesh.",
      "url": "https://www.ndtv.com/india-news/bsf-gets-increased-powers-in-3-border-states-what-it-means-2574644",
      "urlToImage": "https://c.ndtvimg.com/2021-08/eglno7qk_-bsf-recruitment-2021_625x300_10_August_21.jpg",
      "publishedAt": "2021-10-14T03:44:00Z",
      "content": "This move is quickly snowballing into a debate on state autonomy. New Delhi: Border Security Force (BSF) officers will now have the power to arrest, search, and of seizure to the extent of 50 km ins… [+4143 chars]"
    },
    {
      "source": {
        "id": "the-times-of-india",
        "name": "The Times of India"
      },
      "author": "TIMESOFINDIA.COM",
      "title": "5 health conditions that can make your joints hurt - Times of India",
      "description": "Joint pain caused by these everyday issues generally goes away on its own when you stretch yourself a little and flex your muscles.",
      "url": "https://timesofindia.indiatimes.com/life-style/health-fitness/health-news/5-health-conditions-that-can-make-your-joints-hurt/photostory/86994969.cms",
      "urlToImage": "https://static.toiimg.com/photo/86995017.cms",
      "publishedAt": "2021-10-14T03:30:00Z",
      "content": "Depression is a mental health condition, but the symptoms may manifest even on your physical health. Unexpected aches and pain in the joints that you may experience when suffering from chronic depres… [+373 chars]"
    },
    {
      "source": {
        "id": null,
        "name": "The Indian Express"
      },
      "author": "Devendra Pandey",
      "title": "Rahul Dravid likely to be interim coach for New Zealand series - The Indian Express",
      "description": "It’s learnt that a few Australian coaches expressed interest in the job, but the BCCI isn’t keen as they are focussing on an Indian for the role, before they look elsewhere.",
      "url": "https://indianexpress.com/article/sports/cricket/rahul-dravid-likely-to-be-interim-coach-for-new-zealand-series-7570990/",
      "urlToImage": "https://images.indianexpress.com/2021/05/rahul-dravid.jpg",
      "publishedAt": "2021-10-14T03:26:09Z",
      "content": "Rahul Dravid is likely to be approached by the Indian cricket board to be the interim coach for Indias home series against New Zealand. Head coach Ravi Shastri and the core of the support staff will … [+1972 chars]"
    },
    {
      "source": {
        "id": null,
        "name": "CNBCTV18"
      },
      "author": null,
      "title": "Thursday's top brokerage calls: Infosys, Wipro and more - CNBCTV18",
      "description": "Goldman Sachs has maintained its 'sell' rating on Mindtree largely due to expensive valuations, while UBS expects a muted reaction from Wipro's stock. Here are the top brokerage calls for the day:",
      "url": "https://www.cnbctv18.com/market/stocks/thursdays-top-brokerage-calls-infosys-wipro-and-more-11101072.htm",
      "urlToImage": "https://images.cnbctv18.com/wp-content/uploads/2019/03/buy-sell.jpg",
      "publishedAt": "2021-10-14T03:26:03Z",
      "content": "MiniGoldman Sachs has maintained its 'sell' rating on Mindtree largely due to expensive valuations, while UBS expects a muted reaction from Wipro's stock. Here are the top brokerage calls for the day:"
    }
  ]
}
</code></pre><p>Ya que las noticias están contenidas en una lista llamada<code>articles</code>, crearemos una variable <code>articles</code> con el valor <code>res['articles']</code>. Ahora, iteraremos sobre la lista <code>articles</code> anexando cada <code>article["title"]</code> con la lista<code> news_headlines</code>. Entonces mostraremos los primeros cinco últimos titulares de las noticias de esta lista.</p><h3 id="como-agregar-la-funci-n-obtener-el-reporte-del-clima"><strong>Como agregar la función obtener el reporte del clima</strong></h3><p>Para obtener el reporte del clima, usaremos la <a href="https://openweathermap.org/">OpenWeatherMap API</a>. Nos registramos con una cuenta gratuita y obtenemos la APP ID. Asegúrate de agregar la <strong><strong>OPENWEATHER_APP_ID </strong></strong>en el archivo <code>.env</code>.</p><pre><code class="language-python">OPENWEATHER_APP_ID = config("OPENWEATHER_APP_ID")


def get_weather_report(city):
    res = requests.get(
        f"http://api.openweathermap.org/data/2.5/weather?q={city}&amp;appid={OPENWEATHER_APP_ID}&amp;units=metric").json()
    weather = res["weather"][0]["main"]
    temperature = res["main"]["temp"]
    feels_like = res["main"]["feels_like"]
    return weather, f"{temperature}℃", f"{feels_like}℃"</code></pre><p>Según la <a href="https://openweathermap.org/current">OpenWeatherMap API</a>, necesitamos realizar una solicitud GET en la URL mencionada anteriormente con el nombre de la ciudad. Obtendremos una respuesta JSON como:</p><pre><code class="language-json">{
    "coord": {
        "lon": 85,
        "lat": 24.7833
    },
    "weather": [
        {
            "id": 721,
            "main": "Haze",
            "description": "haze",
            "icon": "50d"
        }
    ],
    "base": "stations",
    "main": {
        "temp": 26.95,
        "feels_like": 26.64,
        "temp_min": 26.95,
        "temp_max": 26.95,
        "pressure": 1011,
        "humidity": 36
    },
    "visibility": 3000,
    "wind": {
        "speed": 2.57,
        "deg": 310
    },
    "clouds": {
        "all": 57
    },
    "dt": 1637227634,
    "sys": {
        "type": 1,
        "id": 9115,
        "country": "IN",
        "sunrise": 1637195904,
        "sunset": 1637235130
    },
    "timezone": 19800,
    "id": 1271439,
    "name": "Gaya",
    "cod": 200
}</code></pre><p>Solo necesitamos <code>weather</code>, <code>temperature</code>, y <code>feels_like</code> de la respuesta anterior.</p><h3 id="como-agregar-la-funci-n-para-obtener-las-pel-culas-en-tendencia"><strong>Como agregar la función para obtener las películas en tendencia</strong></h3><p>Para obtener las peliculas en tendencia, usaremos la <a href="https://www.themoviedb.org/">The Movie Database (TMDB)</a> API. Registrate con una cuenta gratuita para obtener la clave API. Agrégala &nbsp;<strong><strong>TMDB_API_KEY </strong></strong>al archivo <code>.env</code>.</p><pre><code class="language-python">TMDB_API_KEY = config("TMDB_API_KEY")


def get_trending_movies():
    trending_movies = []
    res = requests.get(
        f"https://api.themoviedb.org/3/trending/movie/day?api_key={TMDB_API_KEY}").json()
    results = res["results"]
    for r in results:
        trending_movies.append(r["original_title"])
    return trending_movies[:5]</code></pre><p>Justo como hicimos con los titulares, crearemos una lista llamada <code>trending_movies</code>. Entonces, según la API TMDB, haremos una solicitud GET. Uan respuesta JSON como muestra se ve de la siguiente manera:</p><pre><code class="language-json">{
  "page": 1,
  "results": [
    {
      "video": false,
      "vote_average": 7.9,
      "overview": "Shang-Chi must confront the past he thought he left behind when he is drawn into the web of the mysterious Ten Rings organization.",
      "release_date": "2021-09-01",
      "title": "Shang-Chi and the Legend of the Ten Rings",
      "adult": false,
      "backdrop_path": "/cinER0ESG0eJ49kXlExM0MEWGxW.jpg",
      "vote_count": 2917,
      "genre_ids": [28, 12, 14],
      "id": 566525,
      "original_language": "en",
      "original_title": "Shang-Chi and the Legend of the Ten Rings",
      "poster_path": "/1BIoJGKbXjdFDAqUEiA2VHqkK1Z.jpg",
      "popularity": 9559.446,
      "media_type": "movie"
    },
    {
      "adult": false,
      "backdrop_path": "/dK12GIdhGP6NPGFssK2Fh265jyr.jpg",
      "genre_ids": [28, 35, 80, 53],
      "id": 512195,
      "original_language": "en",
      "original_title": "Red Notice",
      "overview": "An Interpol-issued Red Notice is a global alert to hunt and capture the world's most wanted. But when a daring heist brings together the FBI's top profiler and two rival criminals, there's no telling what will happen.",
      "poster_path": "/wdE6ewaKZHr62bLqCn7A2DiGShm.jpg",
      "release_date": "2021-11-04",
      "title": "Red Notice",
      "video": false,
      "vote_average": 6.9,
      "vote_count": 832,
      "popularity": 1990.503,
      "media_type": "movie"
    },
    {
      "genre_ids": [12, 28, 53],
      "original_language": "en",
      "original_title": "No Time to Die",
      "poster_path": "/iUgygt3fscRoKWCV1d0C7FbM9TP.jpg",
      "video": false,
      "vote_average": 7.6,
      "overview": "Bond has left active service and is enjoying a tranquil life in Jamaica. His peace is short-lived when his old friend Felix Leiter from the CIA turns up asking for help. The mission to rescue a kidnapped scientist turns out to be far more treacherous than expected, leading Bond onto the trail of a mysterious villain armed with dangerous new technology.",
      "id": 370172,
      "vote_count": 1804,
      "title": "No Time to Die",
      "adult": false,
      "backdrop_path": "/1953j0QEbtN17WFFTnJHIm6bn6I.jpg",
      "release_date": "2021-09-29",
      "popularity": 4639.439,
      "media_type": "movie"
    },
    {
      "poster_path": "/5pVJ9SuuO72IgN6i9kMwQwnhGHG.jpg",
      "video": false,
      "vote_average": 0,
      "overview": "Peter Parker is unmasked and no longer able to separate his normal life from the high-stakes of being a Super Hero. When he asks for help from Doctor Strange the stakes become even more dangerous, forcing him to discover what it truly means to be Spider-Man.",
      "release_date": "2021-12-15",
      "id": 634649,
      "adult": false,
      "backdrop_path": "/vK18znei8Uha2z7ZhZtBa40HIrm.jpg",
      "vote_count": 0,
      "genre_ids": [28, 12, 878],
      "title": "Spider-Man: No Way Home",
      "original_language": "en",
      "original_title": "Spider-Man: No Way Home",
      "popularity": 1084.815,
      "media_type": "movie"
    },
    {
      "video": false,
      "vote_average": 6.8,
      "overview": "After finding a host body in investigative reporter Eddie Brock, the alien symbiote must face a new enemy, Carnage, the alter ego of serial killer Cletus Kasady.",
      "release_date": "2021-09-30",
      "adult": false,
      "backdrop_path": "/70nxSw3mFBsGmtkvcs91PbjerwD.jpg",
      "vote_count": 1950,
      "genre_ids": [878, 28, 12],
      "id": 580489,
      "original_language": "en",
      "original_title": "Venom: Let There Be Carnage",
      "poster_path": "/rjkmN1dniUHVYAtwuV3Tji7FsDO.jpg",
      "title": "Venom: Let There Be Carnage",
      "popularity": 4527.568,
      "media_type": "movie"
    }
  ],
  "total_pages": 1000,
  "total_results": 20000
}
</code></pre><p>De la respuesta anterior, solo necesitamos el título de la película. Obtenemos <code>results</code> la cual es una lista y entonces iteramos sobre ella para obtener el título de la película y anexarlo a la lista <code>trending_movies</code>. Al final, mostramos los primeros cinco elementos de la lista.</p><h3 id="como-agregar-la-funci-n-para-hacer-chistes-aleatoriamente"><strong>Como agregar la función para hacer chistes aleatoriamente</strong></h3><p>Para obtener un chiste al azar, necesitamos realizar una solicitud GET en la siguiente URL: <a href="https://icanhazdadjoke.com/">https://icanhazdadjoke.com/</a>.</p><pre><code class="language-python">def get_random_joke():
    headers = {
        'Accept': 'application/json'
    }
    res = requests.get("https://icanhazdadjoke.com/", headers=headers).json()
    return res["joke"]</code></pre><h3 id="como-agregar-la-funci-n-para-obtener-un-consejo-al-azar"><strong>Como agregar la función para obtener un consejo al azar</strong></h3><p>Para obtener algún consejo al azar, usaremos la <a href="https://api.adviceslip.com/">Advice Slip API</a>.</p><pre><code class="language-python">def get_random_advice():
    res = requests.get("https://api.adviceslip.com/advice").json()
    return res['slip']['advice']
</code></pre><h2 id="como-crear-el-comando-principal"><strong>Como crear el comando principal</strong></h2><p>Para ejecutar el proyecto, necesitamos crear nuestro comando principal. Crea un archivo <code>main.py</code> y agrégale el siguiente código:</p><pre><code class="language-python">import requests
from functions.online_ops import find_my_ip, get_latest_news, get_random_advice, get_random_joke, get_trending_movies, get_weather_report, play_on_youtube, search_on_google, search_on_wikipedia, send_email, send_whatsapp_message
from functions.os_ops import open_calculator, open_camera, open_cmd, open_notepad, open_discord
from pprint import pprint


if __name__ == '__main__':
    greet_user()
    while True:
        query = take_user_input().lower()

        if 'open notepad' in query:
            open_notepad()

        elif 'open discord' in query:
            open_discord()

        elif 'open command prompt' in query or 'open cmd' in query:
            open_cmd()

        elif 'open camera' in query:
            open_camera()

        elif 'open calculator' in query:
            open_calculator()

        elif 'ip address' in query:
            ip_address = find_my_ip()
            speak(f'Su Dirección IP es {ip_address}.\n Para su comodidad la estoy mostrado en la pantalla señor.')
            print(f'Tu direccion IP es {ip_address}')

        elif 'wikipedia' in query:
            speak('¿Qué quiere buscar en Wikipedia, señor?')
            search_query = take_user_input().lower()
            results = search_on_wikipedia(search_query)
            speak(f"De acuerdo con Wikipedia, {results}")
            speak("Para su comodidad, mostraré en pantalla los resultados, señor.")
            print(results)

        elif 'youtube' in query:
            speak('¿Que desea ver en YouTube, señor?')
            video = take_user_input().lower()
            play_on_youtube(video)

        elif 'search on google' in query:
            speak('¿Qué desea buscar en Google, señor?')
            query = take_user_input().lower()
            search_on_google(query)

        elif "send whatsapp message" in query:
            speak('¿A qué número debería enviar el mensaje señor?, por favor, digítelo en la consola: ')
            number = input("Ingrese el número: ")
            speak("¿Cúal es el mensaje, señor?")
            message = take_user_input().lower()
            send_whatsapp_message(number, message)
            speak("El mensaje ha sido enviado, señor.")

        elif "send an email" in query:
            speak("¿A qué dirección de correo la envío, señor? Por favor, ingresela en la consola: ")
            receiver_address = input("Ingrese la dirección de correo electrónico: ")
            speak("¿Cuál es el asunto, señor?")
            subject = take_user_input().capitalize()
            speak("¿Cuál es el mensaje, señor?")
            message = take_user_input().capitalize()
            if send_email(receiver_address, subject, message):
                speak("El correo ha sido enviado, señor.")
            else:
                speak("Algo ha salido mal mientras estaba enviando el correo, por favor revise el registro de errores, señor.")

        elif 'joke' in query:
            speak(f"Espero le guste este, señor.")
            joke = get_random_joke()
            speak(joke)
            speak("Para su goce, se lo mostraré en la pantalla, señor.")
            pprint(joke)

        elif "advice" in query:
            speak(f"Acá hay un consejo para usted, señor.")
            advice = get_random_advice()
            speak(advice)
            speak("Para su disfrute, lo estoy mostrando en la pantalla, señor.")
            pprint(advice)

        elif "trending movies" in query:
            speak(f"Algunas de las películas en tendencia son: {get_trending_movies()}")
            speak("Para su mejor comprensión, están en la pantalla, señor.")
            print(*get_trending_movies(), sep='\n')

        elif 'news' in query:
            speak(f"Estoy leyendo los útimos titulares de las noticias, señor.")
            speak(get_latest_news())
            speak("Para su comodidad, las mostraré en la pantalla, señor.")
            print(*get_latest_news(), sep='\n')

        elif 'weather' in query:
            ip_address = find_my_ip()
            city = requests.get(f"https://ipapi.co/{ip_address}/city/").text
            speak(f"Obteniendo el reporte del clima en su ciudad {city}")
            weather, temperature, feels_like = get_weather_report(city)
            speak(f"La temperatura actual es {temperature}, pero se siente más como {feels_like}")
            speak(f"Además, el reporte menciona acerca de {weather}")
            speak("Para vuestra información, se la mostraré en la pantalla, señor.")
            print(f"Description: {weather}\nTemperature: {temperature}\nFeels like: {feels_like}")</code></pre><p>Mientras que el código anterior parece bastante extenso, es bastante simple y sencillo de entender.</p><p>Si observas con detenimiento, todo lo que se hizo es importar los módulos requeridos y las funciones en línea y sin conexión. Entonces, dentro del comando principal, la primera cosa que se hace es dar la bienvenida al usuario usando la función <code>greet_user()</code>.</p><p>Luego, ejecutamos un ciclo <em>while</em> para continuamente obtener información del usuario usando la función <code>take_user_input()</code>, Ya que nuestra cadena query está, podemos agregar un filtro <em>if-else</em> &nbsp;para revisar diferentes condiciones en la cadena <code>query</code>.</p><p>Nota: Para Python 3.10, puedes usar <a href="https://www.python.org/dev/peps/pep-0636/">Python Match Case</a> en lugar del filtro <em>if-else</em>.</p><p>Para ejecutar el programa, puedes usar la siguiente instrucción: </p><pre><code class="language-bash">$ python main.py</code></pre><h2 id="conclusi-n"><strong>Conclusión</strong></h2><p>Acabamos de crear nuestro propio asistente personal virtual con la ayuda de Python. Puedes agregar más características a la aplicación si lo deseas. Puedes agregar este proyecto a tu portafolio o ¡solo hacerlo por diversión!</p><p>Para el código completo, revisa el siguiente repositorio en GitHub: <a href="https://github.com/ashutoshkrris/Virtual-Personal-Assistant-using-Python">https://github.com/ashutoshkrris/Virtual-Personal-Assistant-using-Python</a></p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
